Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 确定对象是否为基元类型_Java_Reflection - Fatal编程技术网

Java 确定对象是否为基元类型

Java 确定对象是否为基元类型,java,reflection,Java,Reflection,我有一个Object[]数组,我正试图找到那些是原语的数组。我试图使用Class.isPrimitive(),但似乎我做错了什么: int i = 3; Object o = i; System.out.println(o.getClass().getName() + ", " + o.getClass().isPrimitive()); 打印java.lang.Integer,false 有没有正确的方法或其他选择?对象[]中的类型永远不会是原始类型,

我有一个
Object[]
数组,我正试图找到那些是原语的数组。我试图使用
Class.isPrimitive()
,但似乎我做错了什么:

int i = 3;
Object o = i;

System.out.println(o.getClass().getName() + ", " +
                   o.getClass().isPrimitive());
打印
java.lang.Integer,false


有没有正确的方法或其他选择?

对象[]中的类型永远不会是原始类型,因为您有引用!这里,
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;
    }
}
import java.util.*;
公开课考试
{
公共静态void main(字符串[]args)
{
System.out.println(isWrapperType(String.class));
System.out.println(isWrapperType(Integer.class));
}
私有静态最终集>getWrapperTypes()
{
Set>();
ret.add(Boolean.class);
ret.add(Character.class);
ret.add(Byte.class);
ret.add(简称class);
ret.add(Integer.class);
ret.add(长类);
ret.add(Float.class);
ret.add(双级);
重新添加(作废类别);
返回ret;
}
}

整数
不是一个基元,
类。isPrimitive()
没有说谎。

从Java 1.5及更高版本开始,有一个新功能称为自动装箱。编译器自己做这件事。当它看到机会时,它会将一个基本类型转换为相应的包装器类

这里可能发生的事情是当你宣布

Object o = i;
编译器将编译此语句,如下所示

Object o = Integer.valueOf(i);

这是自动装箱。这将解释您收到的输出

我认为这是由于自动装箱造成的

您可以实现一个实用程序方法,该方法匹配这些特定的装箱类,并给出某个类是否为基元类

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);
}
公共静态布尔isWrapperType(类clazz){
返回clazz.equals(Boolean.class)|
clazz.equals(Integer.class)||
clazz.equals(Character.class)||
clazz.equals(Byte.class)||
clazz.equals(短类)||
clazz.equals(双级)||
clazz.equals(长类)||
clazz.equals(Float.class);
}

您必须处理java的自动装箱问题。
让我们参加codepublic类测试 public class test { public static void main(String [ ] args) { int i = 3; Object o = i; return; } } { 公共静态void main(字符串[]args) { int i=3; 对象o=i; 返回; } }您将获得类test.class和javap-c测试,让我们来检查生成的字节码 Compiled from "test.java" public class test extends java.lang.Object{ public test(); Code: 0: aload_0 1: invokespecial #1; //Method 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; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 6: astore_2 7: return

} 公共类测试扩展了java.lang.Object{ 公开考试(); 代码: 0:aload_0 1:invokespecial#1;//方法java/lang/Object。“:()V 4:返回

公共静态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:返回


}如您所见,java编译器添加了invokestatic#2//方法java/lang/Integer.valueOf:(I)Ljava/lang/Integer;要从int中创建一个新的整数,然后通过astore_2将该新对象存储在o中,正如一些人已经说过的,这是由于

invokestatic #2; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 您可以创建一个实用方法来检查对象的类是否为
Integer
Double
,等等。但是无法知道对象是否是通过自动装箱原语创建的;一旦装箱,它看起来就像是显式创建的对象


因此,除非您确定数组中永远不会包含没有自动装箱的包装类,否则就没有真正的解决方案。

只是为了让您看到isPrimitive可以返回true(因为您有足够的答案说明它为什么为false):

当方法采用“int”而不是“Integer”时,这在反射中很重要

此代码适用于:

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)
    {
    }
}
此代码失败(找不到方法):


primitve包装类型不会响应此值。这是用于原语的类表示,尽管除了反射之外,我想不出它有多少用途。比如说

System.out.println(Integer.class.isPrimitive());
打印“假”,但是


为那些喜欢简洁代码的人打印“true”

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);
}
private static final Set WRAPPER\u TYPES=new HashSet(Arrays.asList(
Boolean.class、Character.class、Byte.class、Short.class、Integer.class、Long.class、Float.class、Double.class、Void.class));
公共静态布尔isWrapperType(类clazz){
返回包装器类型。包含(clazz);
}

从春天抓到小海狸

可能Apache变体(commons beans)也有类似的功能。

有相关的方法

新版本包括:

boolean isPrimitiveOrWrapped = 
    ClassUtils.isPrimitiveOrWrapper(object.getClass());
旧版本有
wrapperToPrimitive(clazz)
方法,该方法将返回原语对应关系

boolean isPrimitiveOrWrapped = 
    clazz.isPrimitive() || ClassUtils.wrapperToPrimitive(clazz) != null;

Google的Guava库有一个检查类是否是原语的包装类型的方法:


Class.isPrimitive()适用于原语

这是我能想到的最简单的方法。包装器类仅存在于
java.lang
包中。除了包装类之外,
java.lang
中没有其他类具有名为
TYPE
的字段。您可以使用它来检查类是否为包装类

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
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;        
}
publicstaticbooleanisboxingclass(Class clazz)
{
String pack=clazz.getPackage().getName();
if(!“java.lang”.equals(pack))
返回false;
尝试
{
clazz.getField(“类型”);
} 
捕获(无此字段例外)
{
返回false;
}           
返回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));
    }
}
import static org.junit.Assert.*;
导入java.lan
boolean isPrimitiveOrWrapped = 
    clazz.isPrimitive() || ClassUtils.wrapperToPrimitive(clazz) != null;
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
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;        
}
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));
    }
}
***objClass.isAssignableFrom(Number.class);***
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;
}