java反射代理机制
来源:互联网 发布:计算机就业前景 知乎 编辑:程序博客网 时间:2024/05/16 04:08
package com.lin.text;
public class Person {
public String name;private String sex;private int age;public void show(){ System.out.println("show::姓名:" + name + "性别:" +sex + "年龄:" + age);}public void shows(String name){ System.out.println("show::姓名:" + name + "性别:" +sex + "年龄:" + age);}@SuppressWarnings("unused")private void showp(){ System.out.println("showp::姓名:" + name + "性别:" +sex + "年龄:" + age);}public String getName() { return name;}public void setName(String name) { this.name = name;}public String getSex() { return sex;}public void setSex(String sex) { this.sex = sex;}public int getAge() { return age;}public void setAge(int age) { this.age = age;}
}
package com.lin.text;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.junit.Test;
public class PersonF {
@Testpublic void main1() throws Exception { // 获取当前类的实例化对象 Class<Person> clazz = Person.class; // 1.创建clazz对应的运行时类Person,用的是clazz.newInstance() // 这里的clazz.newInstance()实际上是调用的是Person类的无参构造器 Person p = clazz.newInstance(); // 2.然后在调用,调用的时候先用clazz.getField(“属性名”)的方法来获取public作用域的属性,然后再往对象里面设值 Field nameF = clazz.getField("name"); nameF.set(p, "我奶妈贼六!"); // 3.获取private作用域的属性值方法比一样,用上面的方法获取不到 //首先应该获取声明的属性 Field sexF = clazz.getDeclaredField("sex"); Field ageF = clazz.getDeclaredField("age"); //将访问权限改为true sexF.setAccessible(true); ageF.setAccessible(true); sexF.set(p, "男"); ageF.set(p, 6); //3.通过反射调用运行类的方法,首先获取方法 Method showF = clazz.getMethod("show"); Method showpF = clazz.getMethod("showp"); //然后调用方法,没有形参的直接showF.invoke(p); showF.invoke(p); //没有设置就会报错 showpF.setAccessible(true); showpF.invoke(p); //调用有形参的方法,clazz.getMethod时需要指明参数的类型 Method showsF = clazz.getMethod("shows", String.class); //有形参的话showsF.invoke(p,形参);传入形参 showsF.invoke(p, "测试入参");}/* * java.lang.Class是反射的源头 * 创建的类通过编译(javac.exe),生成对应点.class文件,之后我们使用的java.exe加载(JVM的类加载器) * .class文件,此。class文件加载到内存以后,就是一个运行时类,放在缓存中,那么这个运行时类本身就是一个Class类 * 1.每个运行时类只加载一次 * 2.有了class实例以后才能进行如下操作 * 1)创建对应的运行时类的对象 * 2)获取对应的运行时类的完整结构(属性、方法、构造器、内部类..) * 3)调用对应的运行时类的指定的结构(属性、方法、构造器) * 4)反射的应用:动态代理 */@SuppressWarnings("rawtypes")@Testpublic void main2() throws Exception { //方法1 Class clazz = Person.class; System.out.println(clazz.getName()); System.out.println(String.class.getName()); //方法2.通过运行时类的对象获取 Person p = new Person(); Class clazz2 = p.getClass(); System.out.println(clazz2.getName()); //方法3.通过Class的静态方法 String classNme = "com.lin.text.Person";// Person路径 Class clazz3 = Class.forName(classNme); System.out.println(clazz3.getName()); //方法4.用类加载器 ClassLoader cl = this.getClass().getClassLoader(); Class clazz4 = cl.loadClass(classNme); System.out.println(clazz4);}//权限修饰符 变量类型 变量名 @SuppressWarnings("rawtypes")@Testpublic void main3() throws Exception { Class clazz = Person.class; Field[] fields = clazz.getDeclaredFields(); for(Field f: fields) { //1.获取每个属性的权限修饰符 int i = f.getModifiers(); //将权限的索引转变成对应的权限名字 String m = Modifier.toString(i); //2.获取每个属性的变量类型 String type = f.getType().getName(); //3.获取每个属性 的变量名 String name = f.getName(); System.out.println(m + "-" + type + "-" + name); }}//获取方法的一些属性@SuppressWarnings("rawtypes")@Testpublic void main4() throws Exception { Class clazz = Person.class; //获取运行时类及其父类中public权限的方法 Method[] methods = clazz.getMethods(); for(Method m : methods) { System.out.println(m.getName() + ": " + Modifier.toString(m.getModifiers()) ); } //getDeclaredMethods是获取该类的中所有方法 Method[] methods2 = clazz.getDeclaredMethods(); for(Method m : methods2) { //获取注解 Annotation[] ann = m.getAnnotations(); for(Annotation a : ann) { System.out.println(a); } //获取形参列表 Class rt = m.getReturnType(); //获取异常类型 System.out.println("方法名:" + m.getName() + "-权限修饰符:" + Modifier.toString(m.getModifiers()) + "-注解:" + ann + "-返回值类型:" + rt); }}
} Java中反射机制主要是应用在动态代理上
:静态代理类和目标对象的类都是在编译期间确定下来的
:动态代理被代理的对象是一个实现抽象接口类,代理的对象是一个实现了InvocationHandler接口的类
静态代理实现:
package com.lin.text;
/**
* 静态代理模式
*/
//接口
interface Factory {
void show();
}
//被代理类
class FactoryImpl implements Factory {
@Overridepublic void show() { System.out.println("代理对象实现代理接口");}
}
//代理类,这里实现了接口,很明显他只能服务Factory这个接口
class ProxyFactory implements Factory {
//声明的时候声明成FactoryFactory f;//创建代理类,传入的是一个被代理类的对象public ProxyFactory(Factory f) { this.f = f;}@Overridepublic void show() { System.out.println("代理类执行"); f.show();}
}
public class TestSaticProxy {
public static void main(String[] args) { //创建被代理的对象 FactoryImpl factory = new FactoryImpl(); //创建代理对象,因为是静态代理,所以这个代理只能为FactoryImpl这一个对象做代理, //当创建新的对象时,将又要创建代理对象,如果被代理的对象很多的话,就要创建很多的代理对象,很不方便 ProxyFactory pf = new ProxyFactory(factory); pf.show();}
}
动态代理:
package com.lin.text;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 动态代理
*/
//被代理类
interface Everything {
void show();
}
//代理类
class EverythingImpl implements Everything {
@Overridepublic void show() { System.out.println("代理类执行");}
}
//创建动态代理类,注意动态代理都要实现一个InvocationHandler的接口
class MyInnvocationHandler implements InvocationHandler {
//实现了接口的被代理类的对象声明,这里由于是因为不能确定被代理类的对象的类,所以同一用Object类,在调用的时候//根据被代理类的类型做适当的强转即可Object obj;//给被代理对象实例化,返回一个代理类的对象public Object blind(Object obj) { this.obj = obj; //三个参数意义(被代理类的类加载器, 被代理类实现的接口, 实现InvocationHandler的类,即动态代理的类) return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);}//当通过代理类的对象发起对被重写的方法调用时,都会转换为如下的invoke方法的调用,即调用具体接口中的方法@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //调用被代理对象的方法,获取返回对象 Object rv = method.invoke(obj, args); return rv;}
}
public class TestDynamicProxy {
public static void main(String[] args) { //被代理对象 EverythingImpl rs = new EverythingImpl(); //创建实现InnvocationHandler接口的动态代理类对象 MyInnvocationHandler mi = new MyInnvocationHandler(); //调用blind()方法,将被代理对象绑定到代理对象上,即设置代理对象 Object obj = mi.blind(rs); //根据具体的被代理对象做强转,都是强转成对象的服务接口,这里的sub就是转成Subject接口对象 Everything sub = (Everything)obj; //调用接口方法 sub.show(); FactoryImpl nike = new FactoryImpl(); obj = mi.blind(nike); Factory pf = (Factory)obj; pf.show();}
}
- java 反射机制、代理
- java反射代理机制
- java 反射和代理机制
- JAVA反射和代理机制
- java 反射和代理机制
- java反射和代理机制
- java反射机制&动态代理
- Java反射机制动态代理
- JAVA的反射机制及代理机制
- java反射机制与动态代理
- Java反射机制与动态代理
- 16---java反射机制05(代理)
- java代理模式与反射机制
- java代理模式与反射机制
- java代理模式与反射机制
- 从代理模式到Java反射机制
- JAVA的反射机制与动态代理
- JAVA反射机制与动态代理
- Android 开发小技巧
- sql语句返回结果是一个类
- 数据结构实验之查找六:顺序查找
- html img标签的alt属性和title属性的作用与区别
- 用接口实现动物声音模拟器
- java反射代理机制
- 在CSDN的博客里面插入代码并且保持格式的秘诀
- jsoup:一款使用 Java 语言开发的 HTML 解析器
- 深度学习第一课:使用autograd来自动求导
- 文本数据库,DateTime 类型新建数据库时(首次运行)出现错误
- centos 安装zookeeper
- Javascript 中call() , applay()理解
- mybatis-generator自动生成代码
- AngularJS(一)