Integer.class与int.class

时间:2014-03-18 05:20:30

标签: java reflection primitive

Integer.classInteger.TYPEint.class之间有什么区别?

acc to me

  1. Integer.class是Integer(Wrapper)类对象的引用
  2. 但是当int.class int不是一个类时,它是一个原始类型。 Integer.TYPE指的是什么?

5 个答案:

答案 0 :(得分:25)

正如您所说,

Integer.class是对Class类型的Integer对象的引用。

int.class是相似性,是对Class类型的int对象的引用。你没错,这听起来不对;原语都有一个Class对象作为特例。如果您想区分foo(Integer value)foo(int value)之间的差异,它对于反思非常有用。

Integer.TYPE(不是Integer.type,请注意)只是int.class的快捷方式。

您可以通过一个简单的程序了解这一点:

public class IntClasses {
  public static void main(String[] args) {
    Class<Integer> a = int.class;
    Class<Integer> b = Integer.TYPE;
    Class<Integer> c = Integer.class;

    System.out.println(System.identityHashCode(a));
    System.out.println(System.identityHashCode(b));
    System.out.println(System.identityHashCode(c));
  }
}

示例输出(每次都会有所不同,但前两个将始终相同,而第三个几乎总是不同):

366712642
366712642
1829164700

答案 1 :(得分:22)

来自java.lang.Class.isPrimitive API

有九个预定义的Class对象来表示八种基本类型和void。它们由Java虚拟机创建,并且与它们表示的基本类型具有相同的名称,即boolean,byte,char,short,int,long,float和double。

这些对象只能通过以下公共静态最终变量java.lang.Boolean.TYPEjava.lang.Integer.TYPE等进行访问

答案 2 :(得分:3)

简单来说:

  

int - &gt;原始...用于简单的数学运算。你无法添加它们   到一个集合。

     

整数 - &gt;对象本身就是int的包装器。即,   它们可以与集合一起使用(因为它们是对象)。他们是   由GC收集为正常对象。

编辑:

public static void main(String[] args) {
    int i = 5;
    System.out.println(int.class);

    Integer i1 = new Integer(5);
    System.out.println(Integer.TYPE);

}

O/P : int
      int

所以,基本上,两者都返回一个int。 Integer.TYPE只返回Integer类的基本类型。对于任何包装类

都是如此

答案 3 :(得分:1)

Java通过为每个原语定义两种类型,以精神分裂的方式处理原始类型与类类型。

例如int是基本类型,Integer是类类型。当您使用泛型时,您被迫使用非基本类型,因此允许ArrayList<Integer>ArrayList<int>不允许。

由于您有时想要执行反射,因此这种二元性会产生两个类(如何检查方法public int foo ();)。

假设你有一个班级:

public class Foo {

    private Integer value;

    public int value1 () {
        return value;
    }

    public Integer value2 () {
        return value;
    }

}

这两个方法并不总是返回相同的值,因为value2()可以返回nullvalue1()会抛出运行时错误。

答案 4 :(得分:0)

对我来说,了解int.classInteger.class的最简单方法是停止认为Integer是包装器(这意味着它是“特殊的”)。实际上,将int视为特例更容易,而且可能更合适。

Integer只是一个普通的Java类,与例如串。它从Object派生而来,其运作方式类似于Object。在运行时,您可以创建Integer的实例,该实例采用类似对象的内存布局,例如开头有一个指向Integer.class的指针,这使得Java的多态运行时行为成为可能。

Integer确实没有什么特别之处。如果您想像一个Java没有布尔,int,长这些原语,而只有Integer,Boolean,Long等,则类型系统实际上是非常一致的。

从概念上讲,出于性能原因,您可以将int视为特殊的。最初,它与Integer无关。在创建Java的时候,对于算术繁重的程序而言,为纯数字维护类似对象的内存布局非常昂贵。而且大多数算术运算甚至根本不涉及多态动态调度。例如。在数字上调用诸如toString之类的方法要少得多。

int在某种意义上是特殊的,因为它是一个类,其“ 实例”布置在内存中,并且剥离了通用对象结构-仅有四个连续的字节,没有多余的元数据。

结果是,您无法执行123.getClass(),因为int 123的运行时内存布局没有类指针。 int.class确实存在,它与Integer.class完全无关(尚未)。从某种意义上讲,int与Void更加相似,因为Void.class确实存在,但是您永远不能在o.class == Void.class所在的地方拥有对象o。

Java可以在这里安顿下来,int是int,Integer是Integer。但是人们意识到,虽然不那么普遍,但是将int视为普通的Java对象仍然非常有用,否则您将始终必须至少维护两组方法-一组使用普通对象,另一组使用普通对象。需要原始语言-即使您不必担心性能。在这些情况下,int实际上表现得像Integer。 Java允许这种转换通过自动装箱过程自动发生,从而有效地使int和Integer相关。

但是int仍然是int,并且Integer仍然是Integer(例如int.class != Integer.class)。但是,Integer.class引入了一个额外的字段来表示它与int.class相关,即Integer.TYPEInteger.TYPE == int.class这样。 对我来说Integer.TYPE只是为了捕捉Integer和int相关的概念。如何使用它,甚至是否有用,取决于您。

实际上,在重要的地方,int和Integer仍然是单独的类型。例如:

void accept (int value);
void accept (Integer value);

仍然被认为是两个重载。因此,在使用反射时,可以使用int.class和Integer.class区分两者。

当不使用反射或某种形式的元编程时,由于无法从对象导航到int.class,因此很少会看到int.class用于代码中。有时会感到困惑,因为自动装箱语法似乎表明您应该获取int.class:

int value = 1;
Class c = ((Object)value).getClass();

但这只是一种幻想,当您进行((Object)value)时,实际上是在创建一个具有相同值的新Integer实例。

我唯一需要显式使用int.class和Integer.class的方法是构建泛型api <T> T getValue(String name, Class<T> type);,在这里我需要区分是否允许api返回null:

int value = getValue("key", Integer.class); // will potentially throw NPE
int value = getValue("key", int.class); // will never throw NPE