|
[笔记]java学习笔记9--反射
1 反射:主要用于工具的开发.所有的重要Java技术底层都会用到反射.反射是一个底层技术.
是在运行时动态分析或使用一个类的工具(是一个能够分析类能力的程序).
反射使我们能够在运行时决定对象的生成和对象的调用.
2 类对象:类类,用来存储和一个类有关的全部信息的类.和对象没关系.
类类:Class类
对象类: Object类
类的对象:new Object();
3 要先有类,再有类对象,类对象没有构造方法.获得Class(类对象)的3种方式:
(1)通过Class.forName("类的全限定名")来获得类对象
Class c1 = Class.forName("Java.lang.String");
Class c2 = Class.forName("day9.Sturnt");
(2)通过类名获得类对象 Class c3 = Student.class;
(3)通过类的对象获得类对象 Class c4 = s.getClass(); //s是Student的引用.
注:第一种方式是最常用最灵活的方式。第一种方式又叫强制类加载.
简单类型也有类对象,在反射中凡是有类型的东西,全部用类对象来表示.
4 Class... 可变长参数.你可以传0或多个参数
public void m(String... s){}
可以这样调用:
m();
m("zhuxy");
m("dush","liqf");
5 一些对象:
Java.lang.reflect.Field对象用来描述属性信息.
Java.lang.reflectMethod对象用来描述方法信息.
Java.lang.reflect.Constructor对象用来描述构造方法信息.
Java.lang.reflect.Package对象用来描述包信息.
Java.lang.reflect.Modifier对象用来描述修饰符信息. //修饰符用整数值表示: 都是2的几次方.
6 通过类对象可以得到:
Class c=Class.forName("java.lang.String");
包 c.getPackage();
修饰符 c.getModifiers();
类名 c.getSimpleName();
父类 c.getSuperclass();
接口 c.getInterfaces();
属性对象 ----- 修饰符 //通过类对象先得到Field对象
类型 //然后通过Field对象得到属性的修饰符,类型,名
名
方法对象 ----- 修饰符 //通过类对象先得到Method对象
返回值类型
方法名
参数类型
构造方法对象-----修饰符 //通过类对象先得到Constructor对象
参数类型
生成对象: (1)c.newInstance(); //Class对象,不能传参数
(2) cons.newInstance(Object o); //Constructor对象,可以传参数
访问属性: f.get(Object ) //Field对象
f.set(object(对象), object(值)); //给哪个属性赋什么值
调用方法: m.invoke(Object obj, Object... args); //Method对象
7 利用反射可以动态生成对象,调用对象的方法,使代码有很大的灵活性,如下例:
//一个学生类
public class Student {
String name;
public Student(){
System.out.println("create Student");
}
public Student(String name){
super();
System.out.println("create Student"+name);
this.name=name;
}
public void study(String course,String teacher){
System.out.println("Student"+name+"study"+course+"by"+teacher);
}
}
public class TestReflection {
public static void main(String[] args) throws Exception{
Class c= Class.forName(args[0]); //args[0]:Student
Class[] ps={String.class}; //参数表
//1得到构造方法对象
Constructor con=c.getConstructor(ps);
Object[] os={args[1]}; //args[1]:zhuxy
//2.通过构造方法对象去构造对象
Object o=con.newInstance(os);
Class[] ps2={String.class,String.class}; //方法参数表
String methodName=args[2]; //要掉的方法名args[2]:study
//3.得到方法对象
Method m=c.getMethod(methodName, ps2);
Object[] os2={args[3],args[4]}; //args[3]:java args[4]:tangliang
//4调用方法
m.invoke(o, os2);
}
}
//上例动态生成了Student类的一个对象zhuxy,并调了它的学习方法.
相当于: Student s=new Student("zhuxy");
s.study("java","tangliang");
8 反射会破坏封装,可以访问私有属性,通过f.setAccessable(true);
也可以访问私有方法,通过m.setAccessable(true);
例:
public class Student {
private String name;
private void move(){
System.out.println(name+": moving!");
}
public static void main(String[] args) {
Class c=Class.forName("Student");
Object obj=c.newInstance();
Field f=c.getDeclaredField("name");
f.setAccessible(true);
f.set(obj,"zhuxy"); //给这个对象obj属性赋值为zhuxy
Method m=c.getDeclaredMethod("move");
m.setAccessible(true);
m.invoke(obj); //调用私有方法
}
}
好好学习,天天向上 |
|