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);
}
}