java反射机制是在运行状态中,对于任何类都能够得知这个类中的属性和方法。
对于任意一个对象,都能够调用它的任意一个方法和属性。
JAVA反射机制的功能:
- 在运行时判断任意属性类;
- 在运行时构造任意一个类方法;
- 在运行时判断任意一个类所具有的方法及属性;
- 在运行时调动任意一个类方法;
- 生成动态代理。
JAVA反射查看类信息:
- 使用Class类的forName(String className)静态方法。该方法需要传入字符串参数,该字符串参数的值是某个类的全限定名;
- 调用某个类的class属性来获取该类对应的Class对象;
- 调用某个对象的getClass()方法。该方法是java.lang.Object类中的一个方法。
Class<?> aClass = Class.forName("com.demo.Reflect");
Class<?> reflectClass= Reflect.class;
Reflect reflect = new Reflect();
Class<? extends Reflect> aClass1 = reflect.getClass();
获取Class成员变量
//获取所有属性
Field[] fields = aClass.getDeclaredFields();
//获取 public 属性
Field[] fields = aClass.getFields();
//获取所有指定属性
Field name = aClass.getDeclaredField("name");
//获取public 指定属性
Field brand = aClass.getField("textBack");
brand.set(obj,new String("我需要修改一个测试"));
String te = (String) brand.get(obj);
System.out.println("\n textBack = "+te);
获取Class对象方法
try {
Class<?> aClass = Class.forName("com.demo.Reflect");
Object obj = aClass.newInstance();
//获取所有的方法
Method[] declaredMethods = aClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
String name = declaredMethod.getName();
AnnotatedType annotatedReturnType = declaredMethod.getAnnotatedReturnType();
System.out.println(name + "\n annotatedType = " + annotatedReturnType.getType());
}
//获取所有 public 方法
Method[] methods = aClass.getMethods();
for (Method method : methods) {
String name = method.getName();
AnnotatedType returnType = method.getAnnotatedReturnType();
Type type = returnType.getType();
System.out.println(name + "\n type = " + type);
}
Method reflect = aClass.getDeclaredMethod("testReflect", String.class);
reflect.setAccessible(true);//打开修改私有方法权限
reflect.invoke(obj, "你好呀");//第一个参数对应调用该方法的实例对象,第二个参数对应该方法的参数
Method getRef = aClass.getDeclaredMethod("getRef");
String invoke = (String) getRef.invoke(obj);
System.out.println(invoke);
return obj;
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
public class Reflect implements Furniture {
private String ref;
private String name;
private double price;
private String brand;
private double discounts;
private String materials;
private String colors;
public String getRef() {
return ref;
}
public void setRef(String ref) {
this.ref = ref;
}
@Override
public String getName() {
return name;
}
@Override
public double getPrice() {
return price;
}
@Override
public String getBrand() {
return brand;
}
@Override
public double getDiscounts() {
return discounts;
}
@Override
public String getMaterials() {
return materials;
}
@Override
public String getColor() {
return colors;
}
public String textBack = "我要做测试";
public void testBack(String test) {
textBack = test;
}
private String annotatedReflect(String ref) {
return ref;
}
private void testReflect(String ref) {
this.ref= ref;
System.out.println(ref);
}
}
代理模式 给某个对象提供一个代理对象,并由代理对象控制对于原对象的访问。
代理模式分类:
- 动态代理模式;
运行时生成的。Java编译完成后并没有实际的class文件。而是在运行时动态生成字节码文件,并加载到JVM。 - 静态代理模式;
在编译时就已经实现好。Java编译完成后代理类是一个实际的class文件。
静态代理实现:
RealSubject 对象以及Proxy对象 都实现了 接口Subject。在Proxy对象中,通过构造函数传递目标对象,然后重写接口Subject方法 request(),在该方法中调用RealSubject对象的request()方法。并可以在方法前后添加其他方法。
RealSubject subject = new RealSubject();
com.demo.Proxy proxy = new com.demo.Proxy(subject);
proxy.request();
public class RealSubject implements Subject {
private static String name = "";
@Override
public void request() {
System.out.println("subject");
}
@Override
public RealSubject reTrue(String str) {
System.out.println(str);
this.name = str;
return this;
}
public String getName() {
return name;
}
}
public class Proxy implements Subject {
private Subject subject;
public Proxy(Subject subject) {
this.subject = subject;
}
@Override
public void request() {
System.out.println("proxySubject");
subject.request();
System.out.println("proxySubject2");
}
@Override
public Proxy reTrue(String str) {
return this;
}
}
代理模式好处: 降低代码耦合度,方便维护。
动态代理:
动态代理主要涉及两个类。一个是 java.lang.reflect.Proxy代理类,另一个是java.lang.reflect.InvocationHandler调用处理器接口,通过重写invoke()方法来执行具体内容。
示例:
第一种方式
RealSubject subject = new RealSubject();
//创建一个 InvocationHandler对象
InvocationHandler proxyHandler = new ProxyHandler(subject);
Class<?> proxyClass = Proxy.getProxyClass(RealSubject.class.getClassLoader(),
RealSubject.class.getInterfaces());
try {
Constructor<?> constructor = proxyClass.getConstructor(InvocationHandler.class);
Subject realSubject = (Subject) constructor.newInstance(proxyHandler);
realSubject.request();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
public interface Subject {
void request();
Subject reTrue(String str);
}
public class RealSubject implements Subject {
private static String name = "";
@Override
public void request() {
System.out.println("subject");
}
@Override
public RealSubject reTrue(String str) {
System.out.println(str);
this.name = str;
return this;
}
public String getName() {
return name;
}
}
public class ProxyHandler implements InvocationHandler {
private Subject subject;
public ProxyHandler(Subject subject) {
this.subject = subject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//定义预处理的工作
System.out.println("=======before=========");
Object result =null;
try {
// method.invoke(subject,"我的天哪");
if (method.getName().equals("reTrue")) {
result = method.invoke(subject, "5555");
}else{
result = method.invoke(subject, args);
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("=======after=========");
return result;
}
}
第二种方式:
private static void instance() {
RealSubject subject = new RealSubject();
//创建一个 InvocationHandler对象
ProxyHandler proxyHandler = new ProxyHandler(subject);
//创建一个动态实例 getClassLoader()将生成的字节码加载到JVM中,getInterfaces()实现所有接口,创建Class对象.
//自定义InvocationHandler
Subject sbj = (Subject) Proxy.newProxyInstance(RealSubject.class.getClassLoader(),
RealSubject.class.getInterfaces(), proxyHandler);
//调用对象方法
sbj.request();
RealSubject RealSubject = (RealSubject)sbj.reTrue("ddd");
System.out.println(RealSubject.getName());
}
public interface Subject {
void request();
Subject reTrue(String str);
}
public class RealSubject implements Subject {
private static String name = "";
@Override
public void request() {
System.out.println("subject");
}
@Override
public RealSubject reTrue(String str) {
System.out.println(str);
this.name = str;
return this;
}
public String getName() {
return name;
}
}
public class ProxyHandler implements InvocationHandler {
private Subject subject;
public ProxyHandler(Subject subject) {
this.subject = subject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//定义预处理的工作
System.out.println("=======before=========");
Object result =null;
try {
// method.invoke(subject,"我的天哪");
if (method.getName().equals("reTrue")) {
result = method.invoke(subject, "5555");
}else{
result = method.invoke(subject, args);
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("=======after=========");
return result;
}
}