黑马程序员技术交流社区

标题: 反射的问题 [打印本页]

作者: 张豪杰    时间: 2013-2-27 20:19
标题: 反射的问题
本帖最后由 张豪杰 于 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);//为什么这里不能调用?
        }
}
作者: 谢波    时间: 2013-2-27 20:59
这个是多态的问题
Object obj=Class.forName("Test2").newInstance();这句话就相当于是Object obj = new Test2();
调用成员变量,是要看左边的,obj是没有a这个成员的
所以,要调用a的话必须强转Test2 test = (Test2)obj;
作者: 付玉光    时间: 2013-2-27 23:44

        本题中当主线程执行完(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);
        }
}


作者: 张豪杰    时间: 2013-2-28 00:05
付玉光 发表于 2013-2-27 23:44
本题中当主线程执行完(Object obj=Class.forName("Test2").newInstance();)
        该句的时候,它都做了以下 ...

太详细了。。
多谢多谢




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