1、 动态语言
2、静态语言
User类
public class User implements Comparable<User> {private String name;public int age;public User(String name, int age) {this.name = name;this.age = age;}private User(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public void show() {System.out.println("调用了show方法");}private void pri(String str){System.out.println("z这是一个私有方法"+str);}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic int compareTo(User o) {return -this.name.compareTo(o.name);}
}
创建并获取和修改User类
@Testpublic void fanshe() throws Exception {Class<User> userClass = User.class;Constructor<User> constructor = userClass.getDeclaredConstructor(String.class, int.class);User lihua = constructor.newInstance("lihua", 77);System.out.println(lihua);// User{name='lihua', age=77}lihua.setAge(66);System.out.println(lihua);// User{name='lihua', age=66}Field age = userClass.getDeclaredField("age");age.set(lihua, 55);System.out.println(lihua);// User{name='lihua', age=55}Method show = userClass.getDeclaredMethod("show");show.invoke(lihua);// 调用了show方法//调用私有构造器Constructor<User> constructor1 = userClass.getDeclaredConstructor(String.class);constructor1.setAccessible(true);User zhangsan = constructor1.newInstance("zhangsan");System.out.println(zhangsan);// User{name='zhangsan', age=0}// 修改私有属性Field name = userClass.getDeclaredField("name");name.setAccessible(true);name.set(zhangsan,"zhangsam1");System.out.println(zhangsan);// User{name='zhangsam1', age=0}// 调用私有方法// Method pri = userClass.getDeclaredMethod("pri")没有参数的写法Method pri = userClass.getDeclaredMethod("pri",String.class);pri.setAccessible(true);pri.invoke(zhangsan,"dsdd");// z这是一个私有方法dsdd}
@Testpublic void classget() throws ClassNotFoundException {// 第一种写法Class<User> userClass = User.class;System.out.println(userClass);// class User// 第二种写法User user = new User();Class<? extends User> aClass = user.getClass();System.out.println(aClass);// class User// 第三种写法(常用)Class<?> user1 = Class.forName("User");System.out.println(user1);// class User// 第四种(了解)test为当前类的名字ClassLoader classLoader = test.class.getClassLoader();Class<?> user2 = classLoader.loadClass("User");System.out.println(user2);// class User}
哪些类型可以有Class对象?
( 1) class:外部类,成员(成员内部类,静态内部类),局部内部类,匿名内部类
( 2) interface:接口
(3)[]:数组
(4) enum:攻举
(5) annotation:注解@interface
(6) primitive type:基本数据类型
( 7) void
@Testpublic void shuzu(){int[] a = new int[10];int[] b = new int[100];int[][] c = new int[10][];Class<? extends int[]> aClass = a.getClass();Class<? extends int[]> aClass1 = b.getClass();Class<? extends int[][]> aClass2 = c.getClass();// 只要类型和维度一样就是同一个ClassSystem.out.println(aClass == aClass1);// true// System.out.println(aClass == aClass2);报错}
@Testpublic void classLoad() throws IOException {Properties properties = new Properties();// 方式一
// FileInputStream inputStream = new FileInputStream("src\\jdbc.properties"); 此方法路径默认在工程下// 方式二ClassLoader classLoader = test.class.getClassLoader();InputStream inputStream = classLoader.getResourceAsStream("jdbc.properties");// 此方法默认在srproperties.load(inputStream);String name = properties.getProperty("name");System.out.println(name);}
使用一个代理将对象包装起来,然后用该代理对象取代原始对象。任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用转到原始对象上。
之前的代理机制的操作,属于静态代理,特征是代理类和目标对象的类都是在编译期间确定下来,不利于程序的扩展。同时,每一个代理类只能为一个接口服务,这样一来程序开发中必然产生过多的代理。最好可以通过一个代理类完成全部的代理功能。
动态代理是指客户通过代理类来调用其它对象的方法,并且是在程序运行时根据需要动态创建目标类的代理对象。
动态代理使用场合:
interface Human{String bef();void eat(String str);}class SuperMan implements Human{@Overridepublic String bef() {return "我相信光";}@Overridepublic void eat(String str) {System.out.println( "我喜欢吃"+str);}}static class ProxyFactory{public static Object getProxyFactory(Object object){MyInvocationHandler myInvocationHandler = new MyInvocationHandler();myInvocationHandler.bind(object);return Proxy.newProxyInstance(object.getClass().getClassLoader(),object.getClass().getInterfaces(), myInvocationHandler);}}static class MyInvocationHandler implements InvocationHandler{// 需要被代理的对象进行赋值private Object object;public void bind(Object object) {this.object = object;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("代理前所作工作");Object invoke = method.invoke(object, args);System.out.println("代理后所作工作");return invoke;}}@Testpublic void DyProxy(){SuperMan superMan = new SuperMan();Human proxyFactory = (Human) ProxyFactory.getProxyFactory(superMan);proxyFactory.bef();proxyFactory.eat("麻辣烫");}
}
CGLIB动态代理
JDK 动态代理有一个的缺陷就是其只能代理实现了接口的类。而CGLIB正好解决了这个问题,在 CGLIB 动态代理机制中 MethodInterceptor
接口和 Enhancer
类是核心
//定义被代理类
class SuperMan{public void whoAmI(){System.out.println("我是超人");}
}
// 定义代理类
class MyMethodInterceptor implements MethodInterceptor{/*o:被代理对象method:被拦截的方法objects:参数methodProxy:调用原始方法*/@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println("你是谁?");// 被增强的方法Object invoke = methodProxy.invokeSuper(o, objects);System.out.println("好的,我知道了!");return invoke;}
}class CglibProxyFactory{public static Object getProxy(Class<?> clazz){// 创建增强类Enhancer enhancer = new Enhancer();// 设置被代理类enhancer.setSuperclass(clazz);// 设置类加载器enhancer.setClassLoader(clazz.getClassLoader());// 设置fenhancer.setCallback(new MyMethodInterceptor());return enhancer.create(); // 创建出代理类}
}
// 执行@Testpublic void ProxyTest(){SuperMan proxy = (SuperMan) CglibProxyFactory.getProxy(SuperMan.class);proxy.whoAmI();}
// 结果
你是谁?
我是超人
好的,我知道了!java
特点:代理类和被代理类编译期间就确定下来了
interface clothFactory{void pro();}class proxyFactory implements clothFactory {private clothFactory clothFactory;public proxyFactory(clothFactory factory) {this.clothFactory = factory;}@Overridepublic void pro() {System.out.println("代理工厂做的前期操作");clothFactory.pro();System.out.println("代理工厂做的后期操作");}}class nike implements clothFactory{@Overridepublic void pro() {System.out.println("nike");}}@Testpublic void proxy(){nike nike = new nike();proxyFactory proxyFactory = new proxyFactory(nike);proxyFactory.pro();}
动态代理相比于静态代理的优点:
抽象角色中(接口)声明的所有方法都被转移到调用处理器一个集中的方法中处理,这样,我们可以更加灵活和统一的处理众多的方法。