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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 张豪杰 中级黑马   /  2013-2-27 20:19  /  1584 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 张豪杰 于 2013-2-28 00:05 编辑

class Test2{
        public static int a=10;
}
public class Test {
        public static void main(String [] args) throws Exception{
                Object obj=Class.forName("Test2").newInstance();//这里的obj是指向Test2的实例对象
                System.out.println(obj.a);//为什么这里不能调用?
        }
}

3 个回复

倒序浏览
这个是多态的问题
Object obj=Class.forName("Test2").newInstance();这句话就相当于是Object obj = new Test2();
调用成员变量,是要看左边的,obj是没有a这个成员的
所以,要调用a的话必须强转Test2 test = (Test2)obj;

评分

参与人数 1黑马币 +6 收起 理由
陈丽莉 + 6

查看全部评分

回复 使用道具 举报

        本题中当主线程执行完(Object obj=Class.forName("Test2").newInstance();)
        该句的时候,它都做了以下动作:
        ①
          Class类是反射的基石,类加载器在编译时不加载Test2类,但在编译时要检查

           java程序语法的正确性,而在运行时才把Test2类加载到内存中,这也

           是java反射独特的优点(可动态加载),而在C/C++中是没有这个特性的。
        ②
          Class类调用它的forName()静态方法把该类加载到内存并返回该类的字

          节码,用Class<?>表示(因为在这一步中被建模的类未知),然后Class<?>类

          使用它的newInstance方法(其实调用的是Constuctor类中的无参构造方法),

          确实创建了一个本类对象,但该方法返回的是它父类型的,原因是因为调用

          这个newInstance方法的字节码是Class<?>,也就是说它没有具体的泛型类型,

          当不知道返回哪个具体类型,但还得返回时,那也就只能返回它父类型的

          了。所以楼主在注释中说的(这里的obj是指向Test2的实例对象)是错误的,

          原因是因为:编译器并不知道Obj是指向Test2的实例对象,因为在编译期

          该类还不存,而是在运行期才加载进来的。 嗨,没办法,你知道我知道,

          但编译器它不知道,所以我们得告诉它,让编译器也知道,怎样才能让它

          也知道呢,那就请兄台看一下我的代码吧。{:soso_e100:}


class Test2{
        public static int a=10;
}
class Test {
        public static void main(String [] args) throws Exception{
                //这里需强制类型转换让编译器知道!
                Test2 test=(Test2)Class.forName("Test2").newInstance();
                System.out.println(test.a);
        }
}

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1 先答到点子上,然后再详细说明是不是更好呢.

查看全部评分

回复 使用道具 举报
付玉光 发表于 2013-2-27 23:44
本题中当主线程执行完(Object obj=Class.forName("Test2").newInstance();)
        该句的时候,它都做了以下 ...

太详细了。。
多谢多谢
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马