A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 王自强 中级黑马   /  2012-9-21 22:29  /  1656 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

int [] a1 = new int[]{1,2,3};
int [] a2 = new int[4];
int[][] a3 = new int[2][3];
String [] a4 = new String[]{"a","b","c"};
System.out.println(a1.getClass() == a2.getClass());//true
//System.out.println(a1.getClass() == a4.getClass());//编译失败  为什么?
//System.out.println(a1.getClass() ==a3.getClass());//编译失败
System.out.println(a1.getClass().getName());//[I  表示该java类是   一维数组,元素类型是int
System.out.println(a1.getClass().getSuperclass().getName());//java.lang.Object
System.out.println(a4.getClass().getSuperclass().getName());
        
Object aObj1 = a1;
Object aOvj2 = a4;
//Object[] aObj3 = a1;//编译失败,这个为什么啊?  
Object[] aObj4 = a3;
Object[] aObj5 = a4;
求解释解释

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1 赞一个!

查看全部评分

9 个回复

倒序浏览
//System.out.println(a1.getClass() == a4.getClass());//编译失败  为什么?
先看看这个一个int型的数组,并不是一个Object对象--在字节码中,但是一个二维的int型的数组就是一个Object对象,一个字符串数组就是
这在张老师的反射中,讲到过,你可以在认真看看 这都是经过验证的

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1 赞一个!

查看全部评分

回复 使用道具 举报
本帖最后由 牛杨 于 2012-9-22 00:15 编辑

这个问题,没有想到。当时 张老师演示的时候没有错……刚刚试了试,还真是出错了。求解!
如果代码写成:
  int [] a1 = new int[]{1,2,3};
  int [] a2 = new int[4];
  int[][] a3 = new int[2][3];
  String [] a4 = new String[]{"a","b","c"};  

  Class clazz1=a1.getClass();
  Class clazz2=a3.getClass();
System.out.println( clazz1 == clazz2 );

Class clazz3=a4.getClass();
System.out.println(clazz1 == clazz3);
就不会出错了。真是费解呀!!!
回复 使用道具 举报
嘛情况,这么不给力。难道大家自己运行这段代码都没问题么?
回复 使用道具 举报
{:soso_e130:}  坚决不让此帖 沉下去
回复 使用道具 举报
还没有人来回答这个问题么?
回复 使用道具 举报
杨志 高级黑马 2012-9-22 14:05:51
7#
这里的问题其实也不是很麻烦!
第一个:
  1. System.out.println(a1.getClass() == a2.getClass());//true
复制代码
这里为什么为true.我想应该都明白!这里只有一份字节码。那么肯定是一样的。所以为true.
那么后面:
  1. System.out.println(a1.getClass() == a4.getClass());
复制代码
这一句为什么会编译失败呢?
而为什么下面这一句又会编译成功呢:
  1.   Class clazz1=a1.getClass();
  2.   Class clazz2=a3.getClass();
复制代码
先说第一个为什么会编译失败。
这里的al.getClass() 得到的是一个一维整形数组的字节码。
而这里的a4.getClass() 得到的却是一个一维String数组的字节码。
这里去比较肯定是不对的。至于==这里就不多说了!
那么关于后面一个问题。
为什么分开去比较就可以编译通过了呢!
这里问题就在于泛型的问题。
  1. Class class1 = al.getClass();
复制代码
这里并没有为其指定参数类型。也就是Class 可以是任何类型的元素。
说个简单点的,我想大家都用过ArrayList吧。
  1. ArrayList arr1 = new ArrayList();
  2.         arr1.add(new Integer(1));
  3.         arr1.add(new String("hello"));
复制代码
上面这段代码肯定是不会报错的。
那么看下面这段:
  1. ArrayList<String> arr2 = new ArrayList<String>();
  2.         arr2.add(new Integer(1));
  3.         arr2.add(new String("hello"));
复制代码
如果这样写!编译器是肯定不会通过的!因为你指定了泛型。
那么回到刚才的这个问题上来!
看如下代码:
  1. Class<? extends int[]> class1 = a1.getClass();
  2.         Class<? extends String[]> class2 = a4.getClass();
  3.         System.out.println(class1 == class2);
复制代码
你们觉得这会通过么!肯定不会!因为本身的类型就不一样!很显然的。
至于你最后一个问题:
  1. Object aObj1 = a1;
  2. Object aOvj2 = a4;
  3. //Object[] aObj3 = a1;//编译失败,这个为什么啊?  
复制代码
这里也一样。a1为一个0bject, 而左边却是一个Object的数组。这肯定是不符合规范的。
如果一定要这样做,可以如下操作:
  1. Object[] obj  = new Object[2];
  2.         obj[0] = a1;
复制代码
好了也差不多了。应牛杨同学的邀请来回答。希望对你有所帮助!加油!

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1 赞一个!

查看全部评分

回复 使用道具 举报
杨志 高级黑马 2012-9-22 14:07:05
8#
牛杨 发表于 2012-9-22 00:07
这个问题,没有想到。当时 张老师演示的时候没有错……刚刚试了试,还真是出错了。求解!
如果代码写成:
  ...

已回答! 可以看下面的回复!你很不错哦!继续加油!
回复 使用道具 举报
牛杨 中级黑马 2012-9-22 18:21:27
9#
杨志 发表于 2012-9-22 14:07
已回答! 可以看下面的回复!你很不错哦!继续加油!

int [] a1 = new int[]{1,2,3};
int [] a2 = new int[4];
int[][] a3 = new int[2][3];
String [] a4 = new String[]{"a","b","c"};
System.out.println(a1.getClass() == a4.getClass());//编译失败  为什么?
刚才又看了看 getClass方法的API文档。
原来是在java 5之后  
a1.getClass()  返回的是一个 Class<? extends int[]>类型的实例对象;
a4.getClass()  返回的是一个  Class<? extends String[]>类型的实例对象。
直接让a1.getClass()、a4.getClass()通过==比较肯定会造成类型不兼容的问题。
如果这么写:
Class clazz1=a1.getClass(); //不会出错时因为 把a1.getClass()的 Class<? extends int[]>进行了向上转型 转成了 Class类型的啦。
Class clazz3=a4.getClass();//不会出错时因为 把a4.getClass()的 Class<? extends String[]>进行了向上转型 转成了 Class类型的啦。
System.out.println(clazz1 == clazz3);

其实通过equals方法来比较就可以了,也即这样写System.out.println((a1.getClass()).equals(a4.getClass()));也不会出错。

总结:
1、== 是比较两个同类型的对象的引用的地址值是否相同。 而equals方法可以比较任意的两个对象的……是否相同。
2、(java API原话)getClass方法的实际结果类型是 Class<? extends |X|>,其中 |X| 表示清除表达式中的静态类型,该表达式调用 getClass。
例如,以下代码片段中不需要强制转换:Number n = 0;
Class<? extends Number> c = n.getClass();

至于 张老师讲课的时候,为啥直接这样写  System.out.println(a1.getClass() == a4.getClass()); 还能编译通过。
我个人认为可能是张老师的Eclipse使用的jdk版本在1.5之之前(1.5之前没有泛型)吧。(貌似我记得张老师头几天讲课时把这个程序的workspace的编译环境故意设置底了点)这个我只是猜想,没有再回过头去验证。

希望 咱们杨版主和我的回答 能让楼主明白哦!

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1 赞一个!

查看全部评分

回复 使用道具 举报
收藏这个问题,作为笔记!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马