黑马程序员技术交流社区

标题: 反射类型疑问 [打印本页]

作者: 王红潮    时间: 2012-9-9 11:53
标题: 反射类型疑问
本帖最后由 王红潮 于 2012-9-9 14:32 编辑

张老师的视频有一段是比较字节码对象的
class Test6
{
public static void main(String[] args)
{
  
  int[] a1 = new int[3];
  int[] a2 = new int[4];
  int[][] a3 = new int[2][3];
  String[] a4 = new String[3];
  System.out.println(a1.getClass() == a2.getClass()); //相同类型
  System.out.println(a1.getClass()== a3.getClass()); //不同类型
  System.out.println(a1.getClass()== a4.getClass()); //不同类型
   System.out.println(int[].class == int[][].class);  //实际上就相当于这样比较了
  System.out.println(int[].class == String[].class);
  System.out.println(a1.getClass().getName());
}
}

这里a1和a2是同一份字节码,可以用“==”,但不同类型的应该用“equals”比较啊,视频里的运行的没有错误,这个跟编译器版本有关系吗,我已经把版本降到1.5了貌似也不能运行,视频里的为什么就没报错呢?

报错信息:
D:\learning\0901>javac Test6.java
Test6.java:11: 错误: 不可比较的类型: Class<CAP#1>和Class<CAP#2>
                System.out.println(a1.getClass()== a3.getClass());
                                                ^
  其中, CAP#1,CAP#2是新类型变量:
    CAP#1从? extends int[]的捕获扩展int[]
    CAP#2从? extends int[][]的捕获扩展int[][]
Test6.java:12: 错误: 不可比较的类型: Class<CAP#1>和Class<CAP#2>
                System.out.println(a1.getClass()== a4.getClass());
                                                ^
  其中, CAP#1,CAP#2是新类型变量:
    CAP#1从? extends int[]的捕获扩展int[]
    CAP#2从? extends String[]的捕获扩展String[]
Test6.java:13: 错误: 不可比较的类型: Class<int[]>和Class<int[][]>
                System.out.println(int[].class == int[][].class);
                                               ^
Test6.java:14: 错误: 不可比较的类型: Class<int[]>和Class<String[]>
                System.out.println(int[].class == String[].class);
                                               ^
4 个错误

但视频里运行是没有错误的(为什么?):


搞明白了,一直按照视频操作的,忘记了泛型是1.5以后的新特性,即使版本降到1.5了还是会检查泛型,降到1.4一下就ok了
作者: 杨震    时间: 2012-9-9 12:03
a1,a2类型是相同的,都是int[]弄的,所以字节码一样,由于字节码中有一份,所以a1.getClass == a2.getClass成立;
a3是int[][]型的,a4是String[]型的,但是他们的getClass返回值都是Class类型的对象,同类型对象是可以用==比较的,
作者: 陈俊来    时间: 2012-9-9 12:56
==比较的是两个变量的值事都相等,对于引用变量表示两个变量在堆中存储的地址是否相同,equals比较的是两个变量是否是对同一个对象的引用。
==比较的是两个对象的地址是否相同,equals比较的是两个对象的内容是否相同,
所以是可以用==比较的。
作者: 王红潮    时间: 2012-9-9 13:16
杨震 发表于 2012-9-9 12:03
a1,a2类型是相同的,都是int[]弄的,所以字节码一样,由于字节码中有一份,所以a1.getClass == a2.getClass ...

视频里的就跟下面的意思一样,但这样不能比较,编译器检查:不可比较的类型
System.out.println(int[].class == int[][].class);  
System.out.println(int[].class == String[].class);

作者: 杨震    时间: 2012-9-9 13:32
王红潮 发表于 2012-9-9 13:16
视频里的就跟下面的意思一样,但这样不能比较,编译器检查:不可比较的类型
System.out.println(int[].c ...

这是由于泛型的问题,int[].class返回的是Class<int[]>类型的对象,而int[][]返回的是Class<int[][]>类型的对象,所以会出错,我写成这样就行了
Class ii = int[].class;
Class jj = int[][].class;
System.out.println(ii == jj); //返回false
作者: 杨震    时间: 2012-9-9 13:54
等高手来回答,我也搞不清楚了,还是没有学透泛型

我估计int[].class和getClass是有区别的,不知道.class是个什么东西,也不是属性,难道是内置?
作者: 武庆东    时间: 2012-9-9 14:09
class Test6
{
public static void main(String[] args)
{
  
  int[] a1 = new int[3];
  int[] a2 = new int[4];
  int[][] a3 = new int[2][3];
  String[] a4 = new String[3];
  System.out.println(a1.getClass() == a2.getClass()); //相同类型,打印true
  System.out.println(a1.getClass()== a3.getClass()); //不同类型,维数不一致,编译出错,不能进行比较
  System.out.println(a1.getClass()== a4.getClass()); //同上
   System.out.println(int[].class == int[][].class);  //同上
  System.out.println(int[].class == String[].class);//类型不一致,int和String编译出错,不能比较
  System.out.println(a1.getClass().getName());
}
}
但不同类型的应该用“equals”比较啊?使用equals比较的是字节码,一个个进行比较!一个类对应的字节码是固定的,他们对应的地址也是固定的,所以只要地址不同那么字节码肯定不同!至于不同类型的字节码,既然是不同类型那么字节码肯定就不会相同了,编译时期就不会通过!


作者: 王红潮    时间: 2012-9-9 14:11
武庆东 发表于 2012-9-9 14:09
class Test6
{
public static void main(String[] args)

张孝祥老师视频里用MyEclipse编译运行时没问题的,为什么?
作者: 武庆东    时间: 2012-9-9 14:18
王红潮 发表于 2012-9-9 14:11
张孝祥老师视频里用MyEclipse编译运行时没问题的,为什么?

那个视频太老了,在jdk1.3, 1.4编译通过!~,也能运行!
作者: 王红潮    时间: 2012-9-9 14:30
武庆东 发表于 2012-9-9 14:18
那个视频太老了,在jdk1.3, 1.4编译通过!~,也能运行!

谢谢,搞明白了,困扰很长时间了,我一直按照视频操作的,把版本降到1.5, 忘记了泛型是1.5的新特性了,只要降到1.4一下就好了,太谢谢了!!!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2