java源文件编译成.class字节码。运行时加载类的时候就是加载.class文件。这也是java为什么可以一次编译多次运行!
只要我们得到.class文件那就可以获得类信息!可以利用反射!
方式一:对象.getClass()
方法是 根对象Object的方法。 是其他类继承Object的getClass方法。
方式二:类名.class,你可以理解为字节码本身就是静态的,类加载的时字节码就进JVM了。所以类.class好比类调用静态方法似得调用字节码对象。
方式三:Class.forName()是Class类的静态方法。参数是字符串,字符串是类的全路径名。
我自己测试的文结构,这个例子仅涉及两个文件。
User.java 为model添加注解,然后利用反射获取注解信息。那我们就可以明白ORM框架注解的原理了,原来是利用反射获取到注解的信息,然后取出来进行sql语句拼写。
操作的文件:fanshe.java
package test;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import annontation.Colum;
import model.User;
public class fanshe {
public static void main(String arge[]) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException{
Class c=Class.forName("model.User");
User s=(User) c.newInstance();
//构造对象
Constructor so=c.getConstructor(int.class,String.class);
User user=(User) so.newInstance(10,"adb");
//获得所有属性
Field[] fields=c.getDeclaredFields();
for(Field f:fields){
Annotation an=f.getDeclaredAnnotation(Colum.class);
print(an+"");
}
Method me=c.getDeclaredMethod("setId",int.class);
me.invoke(s, 200);
print(s.getId()+"");
}
public static void print(String s){
System.out.println(s);
}
}
结果:
@annontation.Colum(name=table_id, length=10)
@annontation.Colum(name=table_name, length=200)
200
利用反射我们可以做到在运行时改变类的结构信息。