Java学习笔记(十一)
反射(Reflection)
通过抽象的一个名字,在记忆中寻找名字相对应的事物,即给定类名,通过反射机制知道类的具体信息(前提,JVM已经加载过这个类),反射相关API:
- java.lang.Class:代表一个类
- java.lang.reflect.Method:代表类的方法
- java.lang.reflect.Field:代表类的成员变量
- java.lang.reflect.Constructor:代表类的构造方法
Class类
Object类中定义了如下方法:
public final Class getClass()
此方法返回类Class能描述Java所有的类。对于每个类而言,JRE都为其保留了一个不变的Class类型的对象,对应于一个加载到JVM中的一个.class文件。Class对象只能由系统建立。每个类的实例都会记得自己是由哪个Class实例所生成的
实例化Class类对象的四种方法
//通过类名.class创建
Class class=String.class;
//已知类的实例,调用类的getClass()方法
Class class="sssss".getClass();
//已知类的全名以及路径
Class class=Class.forName("java.lang.String");
//其他方式
ClassLoader cl=this.getClass().getClassLoader();
Class class=cl.loadClass("String");
通过反射获得类的完整结构
package day1;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Iterator;
public class Test {
public static void main(String[] args) {
try {
//获取反射对象
Class clazz=Class.forName("day1.Student");
//获取反射对象父类
Class supClazz=clazz.getSuperclass();
System.out.println(supClazz.getName());
//获取类接口
Class[] interfaces=clazz.getInterfaces();
for (Class class1 : interfaces) {
System.out.println(class1.getName());
}
//获取类的共有构造方法
Constructor[] cons=clazz.getConstructors();
for (Constructor constructor : cons) {
System.out.println(constructor.getName()+" "+constructor.getModifiers());
}
//获取类的私有构造方法
Constructor[] cons1=clazz.getDeclaredConstructors();
for (Constructor constructor : cons1) {//1代表public 2代表private
System.out.println(constructor.getName()+" "+constructor.getModifiers());
Class[] paramClasses=constructor.getParameterTypes();
for (Class pc : paramClasses) {
System.out.println(pc.getName());
}
}
//通过反射创建对象
Student student=(Student)clazz.newInstance();//无参构造
// System.out.println(student.school);
Constructor c=clazz.getConstructor(String.class);//获取指定参数列表的构造参数
Student student2=(Student)c.newInstance("diyi");
System.out.println(student2.school);
System.out.println("2222");
Constructor c1=clazz.getDeclaredConstructor(int.class);
c1.setAccessible(true);
Student student21=(Student)c1.newInstance(1);
System.out.println(student21.age);
//
System.out.println("------");
//通过反射获取类的共有方法
Method[] ms=clazz.getMethods();
for (Method method : ms) {
System.out.println(method.getName());
System.out.println(method.getReturnType());
System.out.println(method.getModifiers());
Class[] poc=method.getParameterTypes();
if(poc!=null && poc.length>0) {
for (Class pc : poc) {
System.out.println(pc.getName());
}
}else {
}
}
//通过反射方法获取类的属性
Field[] fs=clazz.getDeclaredFields();//获取本类的所有属性
for (Field field : fs) {
System.out.println(field.getType());
System.out.println(field.getName());
}
//获取类的包名
Package p=clazz.getPackage();
System.out.println(p.getName());
//调用类的方法
Method method=clazz.getMethod("setInfo", String.class,int.class);
method.invoke(clazz.getConstructor().newInstance(), "No.1",14);//对象,参数
//调用类的属性
Constructor con1=clazz.getConstructor();
Student student3=(Student)con1.newInstance();
Field field=clazz.getDeclaredField("school");
field.set(student3, "csu");
String school=(String) field.get(student3);
System.out.println(school);
} catch (Exception e) {
// TODO: handle exception
}
}
}
Java动态代理
Proxy:专门完成代理的操作类
package day1;
public class TestDemoImpl implements ITestDemo{
@Override
public void test1() {
// TODO Auto-generated method stub
System.out.println("执行test1()方法");
}
@Override
public void test2() {
// TODO Auto-generated method stub
System.out.println("执行test2()方法");
}
}
package day1;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Test2 {
public static void main(String[] args) {
//如果一个对象想要Proxy.newProxyInstance方法被代理,那么此对象的类一定要有相应的接口
ITestDemo test=new TestDemoImpl();
test.test1();
test.test2();
System.out.println("---------------");
InvocationHandler handler=new ProxyDemo(test);//传入代理对象
ITestDemo t = (ITestDemo)Proxy.newProxyInstance(handler.getClass().getClassLoader(),test.getClass().getInterfaces(), handler);
t.test1();
t.test2();
}
}
package day1;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 动态代理类
* @author xlzz
*
*/
public class ProxyDemo implements InvocationHandler{
Object obj;//被代理的对象
public ProxyDemo(Object obj) {
this.obj=obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
System.out.println(method.getName()+"方法开始执行");
Object resultObject=method.invoke(this.obj, args);//执行代理对象指定的方法
System.out.println(method.getName()+"方法执行完毕");
return null;
}
}
package day1;
public interface ITestDemo {
void test1();
void test2();
}