看了一下Java反射,写一下自己的理解。
JVM在运行时才加载类,一般写的代码都什么问题。Java的反射机制是在编译并不确定是哪个类被加载了,而是在程序运行的时候才加载、探知、自审,使用在编译期并不知道的类,这就是反射。
但是在使用反射之前,需要清楚几个东西。
第一个就是java.lang.Class类,这个类也管理JVM,它有几个重要的方法:
1, public static Class<?> forName(String className) :native 方法,动态加载类。非常重要。
如在sql中动态加载驱动程序:class.forName(sqlDriver);
2,public T newInstance() :根据对象的class新建一个对象,用于反射。非常重要。
可用在反射中构建对象,调用对象方法:
class doubleClass= class.forName("java.lang.Double");
Object objDouble = doubleClass.newInstance();
如在javaBean中就应用了这个方法,因为java默认要有一个无参构造函数。
3, public ClassLoader getClassLoader() :获得类的类加载器Bootstrap ,Extension ,System or user custom ClassLoader(一般为system classloader)。重要。
4,public String getName() :获取类或接口的名字。记住enum为类,annotation为接口。重要
5,public native Class getSuperclass():获取类的父类,继承了父类则返回父类,否则返回java.lang.Object。返回Object的父类为空-null。一般
6,public java.net.URL getResource(String name) :根据字符串获得资源。
Class类的实例表示java应用 运行时的类或接口,例如:
Class<?> cls = LowClass.class;
LowClass cf = (LowClass)cls.newInstance();
cls表示的是LowClass的运行时实例,第二句通过这个运行时实例调用newInstance(),又声明了一个LowClass的对象,这是通过反射得到的。然后这个对象可以去调用它的方法。而cls这个Class对象则可以得到这个运行时类(LowClass)的所有信息,包括它的属性,方法,继承的接口,父类,继承的属性,修饰符,等等。
在Class类中还有一个方法是getClassLoader(),它的意思是将运行时的类装进JVM中。
每个java类运行时都在JVM中表现为一个Class对象,可通过 类名.class,实例对象.getClass(),和Class.forName(类名) 等获取Class类的对象。
getClass()这个方法则是在Object类中的,它的定义如下:
public final native Class<?> getClass();
返回的是一个Class<?> , 表示返回的是一个运行时类,可通过此进行反射。
此方法用native关键字修饰,表示的是:一个java调用非java代码的接口,该方法的实现由非java语言实现,但是使用时和普通java方法并没有什么区别。这个方法已经被实现。
下面贴一个例子:
package cn.swpu;
import java.lang.reflect.*;
/**
* @author
*
*/
abstract class SuperClass{
/**
*
*/
public abstract void sayChinese();
public abstract void sayEnglish();
public String func(){
sayChinese();
sayEnglish();
return "";
}
}
class LowClass extends SuperClass{
/**
*
*/
public void sayChinese() {
// TODO Auto-generated method stub
System.out.println("你好!");
}
public void sayEnglish() {
// TODO Auto-generated method stub
System.out.println("Hello");
}
}
public class Reflect1 {
/**
*
*/
public Reflect1() {
// TODO Auto-generated constructor stub
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Class<? > demo1 = null;
try {
demo1 = Class.forName("cn.swpu.LowClass");
System.out.println("name is:"+demo1);
LowClass lc = (LowClass)demo1.newInstance();
System.out.println(lc.func());
System.out.println("test is:"+demo1.getClass().getName());
System.out.println( demo1.getName());
System.out.println(demo1.getSuperclass().getName());
Field[] fields = demo1.getDeclaredFields();
for(int i=0; i < fields.length; i++){
System.out.println("the field is:"+fields[i].getName());
}
} catch (Exception e) {
// TODO: handle exception
System.out.println("Error");
}
}
}