回答:
の型Object[]
は本当にプリミティブになることはありません -参照があるからです!ここでは、のタイプはi
isですint
が、によって参照されるオブジェクトのタイプo
はInteger
(自動ボックス化のため)です。
タイプが「プリミティブのラッパー」であるかどうかを調べる必要があるようです。これのために標準ライブラリに組み込まれているものはないと思いますが、簡単にコーディングできます。
import java.util.*;
public class Test
{
public static void main(String[] args)
{
System.out.println(isWrapperType(String.class));
System.out.println(isWrapperType(Integer.class));
}
private static final Set<Class<?>> WRAPPER_TYPES = getWrapperTypes();
public static boolean isWrapperType(Class<?> clazz)
{
return WRAPPER_TYPES.contains(clazz);
}
private static Set<Class<?>> getWrapperTypes()
{
Set<Class<?>> ret = new HashSet<Class<?>>();
ret.add(Boolean.class);
ret.add(Character.class);
ret.add(Byte.class);
ret.add(Short.class);
ret.add(Integer.class);
ret.add(Long.class);
ret.add(Float.class);
ret.add(Double.class);
ret.add(Void.class);
return ret;
}
}
java.lang.<type>.TYPE
、結局のところ、プリミティブ自体でしか機能しません。素晴らしい解決策のおかげで、私は各タイプを個別にチェックすることを避けられないようです。
HashSet
はO(1)でのアクセスを許可しますが、最悪の場合if
、switch
ステートメントの行またはステートメントはO(#のラッパー)を必要とします。実際にif
は、固定数の9ラッパーのステートメントが、ハッシュベースのアクセスよりも高速でない可能性があるかどうかは疑問です。
commons-langに ClassUtils
は関連するメソッドがあります。
新しいバージョンは次のとおりです。
boolean isPrimitiveOrWrapped =
ClassUtils.isPrimitiveOrWrapper(object.getClass());
古いバージョンにはwrapperToPrimitive(clazz)
、プリミティブな対応を返すメソッドがあります。
boolean isPrimitiveOrWrapped =
clazz.isPrimitive() || ClassUtils.wrapperToPrimitive(clazz) != null;
GoogleのGuavaライブラリには、クラスがプリミティブのラッパータイプかどうかをチェックするPrimitivesユーティリティがありますPrimitives.isWrapperType(class)
。
Class.isPrimitive()はプリミティブに対して機能します
簡潔なコードが好きな人のために。
private static final Set<Class> WRAPPER_TYPES = new HashSet(Arrays.asList(
Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class, Void.class));
public static boolean isWrapperType(Class clazz) {
return WRAPPER_TYPES.contains(clazz);
}
void.class.isPrimitive()
はtrueを返します
Void
はnull
;)です。Callable<Void>
これは、何も返さないCallableであるa を作成する場合に役立ちます。
Java 1.5以降では、オートボクシングと呼ばれる新機能があります。コンパイラはこれを自分で行います。機会を見つけると、プリミティブ型を適切なラッパークラスに変換します。
おそらくここで起こっているのは宣言するときです
Object o = i;
コンパイラはこのステートメントを次のようにコンパイルします
Object o = Integer.valueOf(i);
これはオートボクシングです。これは、受け取っている出力を説明します。Java 1.5仕様のこのページでは、自動ボックス化について詳しく説明しています。
Integer.valueOf(int)
自体は、引数が「バイト」の場合にのみキャッシュされた値を返します(読み取り:-128〜127の両方を含みます)。それ以外の場合はを呼び出しますnew Integer(int)
。参照:developer.classpath.org/doc/java/lang/...、hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/...
これはオートボクシングが原因で発生すると思います。
int i = 3;
Object o = i;
o.getClass().getName(); // prints Integer
これらの特定のボクシングクラスに一致するユーティリティメソッドを実装して、特定のクラスがプリミティブであるかどうかを確認できます。
public static boolean isWrapperType(Class<?> clazz) {
return clazz.equals(Boolean.class) ||
clazz.equals(Integer.class) ||
clazz.equals(Character.class) ||
clazz.equals(Byte.class) ||
clazz.equals(Short.class) ||
clazz.equals(Double.class) ||
clazz.equals(Long.class) ||
clazz.equals(Float.class);
}
.equals
し==
。クラスはシングルトンです。
Javaの自動ボクシングに対処する必要があります。
コードを見てみましょう
パブリッククラステスト { public static void main(String [] args) { int i = 3; オブジェクトo = i; 戻る; } }クラスtest.classとjavap -c testを取得すると、生成されたバイトコードを検査できます。
「test.java」からコンパイル public class testはjava.lang.Object {を拡張します public test(); コード: 0:aload_0 1:invokespecial#1; //メソッドjava / lang / Object。 "" :()V 4:戻るあなたが見ることができるように追加されたJavaコンパイラpublic static void main(java.lang.String []); コード: 0:iconst_3 1:istore_1 2:iload_1 3:invokestatic#2; //メソッドjava / lang / Integer.valueOf:(I)Ljava / lang / Integer; 6:astore_2 7:戻る
}
invokestatic#2; //メソッドjava / lang / Integer.valueOf:(I)Ljava / lang / Integer;intから新しいIntegerを作成し、astore_2を介してoにその新しいオブジェクトを格納します
public static boolean isValidType(Class<?> retType)
{
if (retType.isPrimitive() && retType != void.class) return true;
if (Number.class.isAssignableFrom(retType)) return true;
if (AbstractCode.class.isAssignableFrom(retType)) return true;
if (Boolean.class == retType) return true;
if (Character.class == retType) return true;
if (String.class == retType) return true;
if (Date.class.isAssignableFrom(retType)) return true;
if (byte[].class.isAssignableFrom(retType)) return true;
if (Enum.class.isAssignableFrom(retType)) return true;
return false;
}
isPrimitiveがtrueを返すことが可能であることを確認できるように(これがfalseである理由を示す十分な回答があるため):
public class Main
{
public static void main(final String[] argv)
{
final Class clazz;
clazz = int.class;
System.out.println(clazz.isPrimitive());
}
}
これは、メソッドが "Integer"ではなく "int"を受け取る場合の反映で重要です。
このコードは機能します:
import java.lang.reflect.Method;
public class Main
{
public static void main(final String[] argv)
throws Exception
{
final Method method;
method = Main.class.getDeclaredMethod("foo", int.class);
}
public static void foo(final int x)
{
}
}
このコードは失敗します(メソッドが見つかりません):
import java.lang.reflect.Method;
public class Main
{
public static void main(final String[] argv)
throws Exception
{
final Method method;
method = Main.class.getDeclaredMethod("foo", Integer.class);
}
public static void foo(final int x)
{
}
}
primitveラッパータイプはこの値に応答しません。これはプリミティブのクラス表現用ですが、リフレクションを除いて、それをあまり多く使用することは考えられません。したがって、たとえば
System.out.println(Integer.class.isPrimitive());
「false」を出力しますが、
public static void main (String args[]) throws Exception
{
Method m = Junk.class.getMethod( "a",null);
System.out.println( m.getReturnType().isPrimitive());
}
public static int a()
{
return 1;
}
「true」を出力します
私はショーに遅れますが、フィールドをテストしている場合は、以下を使用できますgetGenericType
。
import static org.junit.Assert.*;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import org.junit.Test;
public class PrimitiveVsObjectTest {
private static final Collection<String> PRIMITIVE_TYPES =
new HashSet<>(Arrays.asList("byte", "short", "int", "long", "float", "double", "boolean", "char"));
private static boolean isPrimitive(Type type) {
return PRIMITIVE_TYPES.contains(type.getTypeName());
}
public int i1 = 34;
public Integer i2 = 34;
@Test
public void primitive_type() throws NoSuchFieldException, SecurityException {
Field i1Field = PrimitiveVsObjectTest.class.getField("i1");
Type genericType1 = i1Field.getGenericType();
assertEquals("int", genericType1.getTypeName());
assertNotEquals("java.lang.Integer", genericType1.getTypeName());
assertTrue(isPrimitive(genericType1));
}
@Test
public void object_type() throws NoSuchFieldException, SecurityException {
Field i2Field = PrimitiveVsObjectTest.class.getField("i2");
Type genericType2 = i2Field.getGenericType();
assertEquals("java.lang.Integer", genericType2.getTypeName());
assertNotEquals("int", genericType2.getTypeName());
assertFalse(isPrimitive(genericType2));
}
}
Oracleのドキュメントは 8つのプリミティブ型をリストアップ。
これは私が考えることができる最も簡単な方法です。ラッパークラスはjava.lang
パッケージにのみ存在します。また、ラッパークラスを除いて、他のクラスにjava.lang
はというフィールドはありませんTYPE
。これを使用して、クラスがWrapperクラスかどうかを確認できます。
public static boolean isBoxingClass(Class<?> clazz)
{
String pack = clazz.getPackage().getName();
if(!"java.lang".equals(pack))
return false;
try
{
clazz.getField("TYPE");
}
catch (NoSuchFieldException e)
{
return false;
}
return true;
}
SpringからBeanUtilsを 入手するhttp://static.springsource.org/spring/docs/3.0.x/javadoc-api/
おそらく、Apacheのバリエーション(Commons Bean)にも同様の機能があります。
public class CheckPrimitve {
public static void main(String[] args) {
int i = 3;
Object o = i;
System.out.println(o.getClass().getSimpleName().equals("Integer"));
Field[] fields = o.getClass().getFields();
for(Field field:fields) {
System.out.println(field.getType());
}
}
}
Output:
true
int
int
class java.lang.Class
int
javapoetのユーザーには、次の方法もあります。
private boolean isBoxedPrimitive(Class<?> type) {
return TypeName.get(type).isBoxedPrimitive();
}
int.class.isPrimitive()
yieldstrue
です。Integer.class.isPrimitive()
利回りfalse
。