_Object[]
_配列があり、プリミティブな配列を見つけようとしています。 Class.isPrimitive()
を使用しようとしましたが、何か間違ったことをしているようです:
_int i = 3;
Object o = i;
System.out.println(o.getClass().getName() + ", " +
o.getClass().isPrimitive());
_
_Java.lang.Integer, false
_を出力します。
正しい方法や代替手段はありますか?
Object[]
は決して本当にプリミティブになりません-参照を持っているからです!ここで、i
の型は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;
}
}
commons-langClassUtils
には関連するmethodsがあります。
新しいバージョンには次のものがあります。
_boolean isPrimitiveOrWrapped =
ClassUtils.isPrimitiveOrWrapper(object.getClass());
_
古いバージョンにはwrapperToPrimitive(clazz)
メソッドがあり、primitiveの対応を返します。
_boolean isPrimitiveOrWrapped =
clazz.isPrimitive() || ClassUtils.wrapperToPrimitive(clazz) != null;
_
GoogleのGuavaライブラリには、クラスがプリミティブのラッパータイプであるかどうかをチェックするPrimitivesユーティリティがあります。 http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/primitives/ Primitives.html
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);
}
Java 1.5以降では、オートボクシングと呼ばれる新しい機能があります。コンパイラはこれを実行します。機会があると、プリミティブ型を適切なラッパークラスに変換します。
おそらくここで起こっているのはあなたが宣言するときです
Object o = i;
コンパイラはこのステートメントを次のようにコンパイルします
Object o = Integer.valueOf(i);
これは自動ボクシングです。これは、受け取っている出力を説明します。 Java 1.5仕様のこのページでは、オートボクシングについて詳しく説明しています。
Integer
はプリミティブではなく、Class.isPrimitive()
は嘘ではありません。
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;
}
これはauto-boxingが原因で起こると思います。
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);
}
Javaのオートボクシングに対処する必要があります。
コードを取得しましょう
public class test { public static void main(String [] args) { int i = 3; Object o = i; return; } }javap -cテスト
「test.Java」 public class test extends Java.lang.Object { public test(); Code: 0:aload_0 1:特別な#1を呼び出します。 //メソッドJava/lang/Object。 "" :()V 4:return
public static void main(Java.lang.String []); Code: 0:iconst_3 1:istore_1 2:iload_1 3:invokestatic#2; //メソッドJava/lang/Integer.valueOf:(I)Ljava/lang/Integer; 6:astore_2 7:return
}
invokestatic#2; //メソッドJava/lang/Integer.valueOf:(I)Ljava/lang/Integer;その新しいオブジェクト
IsPrimitiveがtrueを返すことが可能であることがわかります(falseである理由を示す十分な回答があるため)。
public class Main
{
public static void main(final String[] argv)
{
final Class clazz;
clazz = int.class;
System.out.println(clazz.isPrimitive());
}
}
これは、メソッドが「整数」ではなく「整数」を受け入れる場合に反映されます。
このコードは機能します:
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)
{
}
}
すでに数人が言っているように、これは autoboxing によるものです。
オブジェクトのクラスがInteger
、Double
などであるかどうかを確認するユーティリティメソッドをcould作成します。ただし、オブジェクトがプリミティブのオートボックス化によって作成されたかどうかを知る方法はありません;ボックス化されると、明示的に作成されたオブジェクトのように見えます。
そのため、オートボクシングなしでは配列にラッパークラスが含まれないことが確実でない限り、実際の解決策はありません。
私はショーに遅れていますが、フィールドをテストしている場合は、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 docs は、8つのプリミティブ型をリストします。
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」を出力します
SpringからBeanUtilsを入手 http://static.springsource.org/spring/docs/3.0.x/javadoc-api/
おそらく、Apacheのバリエーション(Commons Bean)にも同様の機能があります。
これは私が考えることができる最も簡単な方法です。ラッパークラスは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;
}
以下のステートメントにより、オブジェクトがラッパータイプかどうかを判断できます。
***objClass.isAssignableFrom(Number.class);***
また、isPrimitive()メソッドを使用してプリミティブオブジェクトを決定することもできます
少なくとも私にとって、この質問はまだ10年あります...プリミティブのインスタンスで機能しない場合、「isPrimitive」の結び付きは何ですか?私は「int.class」が原始的であることを知っているので、これを尋ねる必要はありません...さて、私はこれを作りました:
import Java.lang.reflect.*;
class Test{
public static void main(String[] args) throws Exception{
char x=3; boolean b=true; int i=2;
Object o= i;
Object name =o.getClass().getField("TYPE").get(o);
System.out.println(""+name);
}
}
これは、「int」、「char」、「boolean」などの文字列を返します。8つのプリミティブにはすべて、これらの値を含む「TYPE」フィールドを持つラッパークラスがあります。 void型も同様です。
別の方法、実用的な使用:
import Java.util.*;
import Java.lang.reflect.*;
class Test{
static void print(Object O){System.out.println(O);}
public static void main(String[] args) throws Exception{
List list2 = new ArrayList<Object>(List.of("Word",2,3.0f,4.0,(char)65, a)); //where a= any user class instance.
//And see like this list simulates a Tuple like in Pyhton, another lack i see in Java.
//But indeed, this kind of List<Object> is still better then a immutable Tuple.
//And this was another of my doubts (tuples), and of other's people, as i've seen in my searchs at web.
ver(list2);
}
static void ver(List lis){
List prims = new ArrayList<String>(List.of("Boolean","Character","Byte","Double","Float","Integer","Long","Short"));
for(Object o: lis){
String s=o.getClass().getSimpleName();
print((prims.contains(s)?"Yes":"No"));
}
}
出力:いいえはいはいはいはいいいえ
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