Java温故而知新-反射机制
发布日期:2021-05-08 10:46:37 浏览次数:7 分类:原创文章

本文共 31699 字,大约阅读时间需要 105 分钟。

认识反射机制

package com.yootk.demo;class Book {       public void read() {           System.out.println("认真学习李兴华老师出版的《Java从入门到项目实战》");    }}public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           Book book = new Book() ; // 1,首先获取Book类的实例化对象        book.read(); // 通过实例化对象进行方法调用。    }}

package com.yootk.demo;class Book {       public void read() {           System.out.println("认真学习李兴华老师出版的《Java从入门到项目实战》");    }}public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           Book book = new Book() ; // 1,首先获取Book类的实例化对象        System.out.println(book.getClass().getName());  // 对象所属类的完整名称        System.out.println(book.getClass().getSimpleName()); // 对象所属类的简化名称(不包含包名称)        System.out.println(book.getClass().getTypeName()); // 获得对象所属类的类型    }}

获取操作类型

package com.yootk.demo;class Book {       public void read() {           System.out.println("认真学习李兴华老师出版的《Java从入门到项目实战》");    }}public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           Book book = new Book() ;        printClass(book.getClass());        printClass(new java.util.Date().getClass());    }    public static void printClass(Class<?> clazz) {           System.out.println("【当前操作的类型】" + clazz.getName());    }}

Class类与对象实例化

范例一

package com.yootk.demo;interface IBook {   }public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           Class<?> clazzA = IBook.class ; //  属于Java的原生语法支持        Class<?> clazzB = java.util.Date.class ; //  属于Java的原生语法支持        System.out.println(clazzA);        System.out.println(clazzB);    }}

范例二

package com.yootk.demo;import java.util.Date;public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           Class<?> clazz = Date.class ; //  属于Java的原生语法支持        System.out.println(clazz);    }}

范例三:

package com.yootk.demo;public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           Class<?> clazz = Class.forName("java.util.Date") ; // 根据类名称实现信息加载        System.out.println(clazz);    }}

反射机制与对象实例化

1package com.yootk.demo;class Book {       public Book() {           System.out.println("【Book】实例化新的Book类对象");    }}public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           Book book = new Book() ;    }}2package com.yootk.demo;class Book {       public Book() {           System.out.println("【Book】实例化新的Book类对象");    }}public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           Class<?> bookClazz = Class.forName("com.yootk.demo.Book") ; // 实例化Book类的对象        bookClazz.newInstance() ; // 在JDK 1.8的时候依然可以正常使用    }}3package com.yootk.demo;class Book {       public Book() {           System.out.println("【Book】实例化新的Book类对象");    }}public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           Class<?> bookClazz = Class.forName("com.yootk.demo.Book") ; // 实例化Book类的对象        bookClazz.getDeclaredConstructor().newInstance() ;    }}4package com.yootk.demo;class Book {       public void read() {           System.out.println("认真学习李兴华老师出版的《Java从入门到项目实战》");    }}public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           Class<?> bookClazz = Class.forName("com.yootk.demo.Book") ; // 实例化Book类的对象        // newInstance()返回的是一个Object类型,那么就必须进行对象的强制向下转型        Book book = (Book) bookClazz.getDeclaredConstructor().newInstance() ;        book.read();    }}5package com.yootk.demo;import java.util.Date;public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           Class<?> bookClazz = Class.forName("java.util.Date") ; // 实例化Book类的对象        // 如果强制转型了,那么就必须进行开发包的完整导入        Date date = (Date) bookClazz.getDeclaredConstructor().newInstance() ;        System.out.println(date.getTime());    }}6package com.yootk.demo;interface IBook {      // 接口    public void read() ;}class MathBook implements IBook {       @Override    public void read() {           System.out.println("【MathBook】认真学习大学数学课程(线性代数、概率统计、离散数学)。");    }}class ProgramBook implements IBook {       @Override    public void read() {           System.out.println("【ProgramBook】认真学习李兴华老师出版的《Java从入门到项目实战》。");    }}class Factory {       private Factory() {   }    public static IBook getInstance(String className) {           if ("math".equalsIgnoreCase(className)) {               return new MathBook() ;        } else if ("program".equalsIgnoreCase(className)) {               return new ProgramBook() ;        } else {               return null ;        }    }}public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           IBook book = Factory.getInstance("program") ;        book.read();    }}7package com.yootk.demo;interface IBook {      // 接口    public void read() ;}class MathBook implements IBook {       @Override    public void read() {           System.out.println("【MathBook】认真学习大学数学课程(线性代数、概率统计、离散数学)。");    }}class ProgramBook implements IBook {       @Override    public void read() {           System.out.println("【ProgramBook】认真学习李兴华老师出版的《Java从入门到项目实战》。");    }}class Factory {       private Factory() {   }    public static IBook getInstance(String className) {    // 必须传递类的完整名称        try {    // 直接实例化对象            Object obj = Class.forName(className).getDeclaredConstructor().newInstance();            if (obj instanceof IBook) {    // 为了防止出现ClassCastException                return (IBook) obj ; // 强制性的向下转型            }            return null ;        } catch (Exception e) {               return null ;        }    }}public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           IBook book = Factory.getInstance("com.yootk.demo.ProgramBook") ;        book.read();    }}8package com.yootk.demo;class Singleton {      // 单例设计类    private static Singleton instance ; // 不进行对象实例化    private Singleton() {    // 构造方法私有化        System.out.println("【" + Thread.currentThread().getName() + "】实例化Singleton类的对象。");    }    public String toString() {           return "【VIP】李兴华编程训练营:yootk.ke.qq.com" ;    }    public static Singleton getInstance() {    // 获取Singleton类实例化对象        if (instance == null) {    // 现在还没有实例化            instance = new Singleton() ; // 对象实例化        }        return instance ; // 获取对象实例    }}public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           for (int x = 0 ;  x < 10 ; x ++) {               Singleton singleton = Singleton.getInstance(); // 获取实例化对象            System.out.println(singleton);        }    }}9package com.yootk.demo;class Singleton {      // 单例设计类    private static Singleton instance ; // 不进行对象实例化    private Singleton() {    // 构造方法私有化        System.out.println("【" + Thread.currentThread().getName() + "】实例化Singleton类的对象。");    }    public String toString() {           return "【VIP】李兴华编程训练营:yootk.ke.qq.com" ;    }    public static Singleton getInstance() {    // 获取Singleton类实例化对象        if (instance == null) {    // 现在还没有实例化            instance = new Singleton() ; // 对象实例化        }        return instance ; // 获取对象实例    }}public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           for (int x = 0 ;  x < 10 ; x ++) {               new Thread(()->{                   Singleton singleton = Singleton.getInstance(); // 获取实例化对象                System.out.println(singleton);            }, "单例操作线程 - " + x).start();        }    }}10package com.yootk.demo;class Singleton {      // 单例设计类    private static Singleton instance ; // 不进行对象实例化    private Singleton() {    // 构造方法私有化        System.out.println("【" + Thread.currentThread().getName() + "】实例化Singleton类的对象。");    }    public String toString() {           return "【VIP】李兴华编程训练营:yootk.ke.qq.com" ;    }    public static synchronized Singleton getInstance() {    // 获取Singleton类实例化对象        if (instance == null) {    // 现在还没有实例化            instance = new Singleton() ; // 对象实例化        }        return instance ; // 获取对象实例    }}public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           for (int x = 0 ;  x < 10 ; x ++) {               new Thread(()->{                   Singleton singleton = Singleton.getInstance(); // 获取实例化对象                System.out.println(singleton);            }, "单例操作线程 - " + x).start();        }    }}11package com.yootk.demo;class Singleton {      // 单例设计类    private static volatile Singleton instance ; // 不进行对象实例化    private Singleton() {    // 构造方法私有化        System.out.println("【" + Thread.currentThread().getName() + "】实例化Singleton类的对象。");    }    public String toString() {           return "【VIP】李兴华编程训练营:yootk.ke.qq.com" ;    }    public static Singleton getInstance() {    // 获取Singleton类实例化对象        if (instance == null) {    // 现在还没有实例化            synchronized (Singleton.class) {    // 同步代码块                if (instance == null) {                       instance = new Singleton(); // 对象实例化                }            }        }        return instance ; // 获取对象实例    }}public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           for (int x = 0 ;  x < 10 ; x ++) {               new Thread(()->{                   Singleton singleton = Singleton.getInstance(); // 获取实例化对象                System.out.println(singleton);            }, "单例操作线程 - " + x).start();        }    }}

反射机制与类结构操作

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

范例1:获取包的信息

package com.yootk.demo;interface IBook {   }interface ISpec {   }abstract class AbstractPrint {   }class Book extends AbstractPrint implements IBook, ISpec {   }public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           Class<?> clazz = Class.forName("com.yootk.demo.Book") ;        System.out.println(clazz.getPackage()); // 返回Package对象实例        System.out.println(clazz.getPackageName());    }}

范例2:获取继承的父类和实现的接口

package com.yootk.demo;interface IBook {   }interface ISpec {   }abstract class AbstractPrint {   }class Book extends AbstractPrint implements IBook, ISpec {   }public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           Class<?> clazz = Class.forName("com.yootk.demo.Book") ;        Class<?> superClazz = clazz.getSuperclass() ;  // 获取父类        System.out.println("【继承父类】" + superClazz.getName());        System.out.println("【继承父类】" + superClazz.getSuperclass().getName());        Class<?> inters [] = clazz.getInterfaces() ; // 获取实现的接口        for (Class<?> temp : inters) {               System.out.println("【实现接口】" + temp.getName());        }    }}

反射获取构造方法

在这里插入图片描述

反射获取全部构造

package com.yootk.demo;import java.lang.reflect.Constructor;class Book {       // Book类中的构造方法使用了不同的访问权限    public Book() {   }    protected Book(String title) {   }    Book(String title, String author) {   }    private Book(String title, String author, double price) {   }}public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           Class<?> clazz = Class.forName("com.yootk.demo.Book") ;        {               System.out.println("--------------------- getConstructors()获取构造 ---------------------");            for (Constructor<?> constructor : clazz.getConstructors()) {                   System.out.println("【1 - 构造信息】" + constructor);            }        }        {               System.out.println("--------------------- getDeclaredConstructors()获取构造 ---------------------");            for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {                   System.out.println("【2 - 构造信息】" + constructor);            }        }    }}

在这里插入图片描述
在这里插入图片描述

通过反射使用有参构造实例化对象

package com.yootk.demo;import java.lang.reflect.Constructor;class Book {       // Book类中的构造方法使用了不同的访问权限    private String title;    private String author;    private double price;    public Book(String title, String author, double price) {           this.title = title;        this.author = author;        this.price = price;    }// 本类中的无参构造、setter、getter方法,略...    public String toString() {           return "【Book】图书名称:" + this.title + "、图书作者:" + this.author + "、图书价格:" + this.price ;    }}public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           Class<?> clazz = Class.forName("com.yootk.demo.Book");        Constructor<?> constructor = clazz.getDeclaredConstructor(String.class, String.class, double.class);// 获取指定构造        Object obj = constructor.newInstance("Java从入门到项目实战", "李兴华", 99.8) ; // 反射对象实例化        System.out.println(obj);    }}

反射调用方法

package com.yootk.demo;import java.lang.reflect.Method;class Book {       public void read() throws RuntimeException {   }}public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           Class<?> clazz = Class.forName("com.yootk.demo.Book");        Method methods [] = clazz.getMethods() ;        for (Method method : methods) {               System.out.println(method);        }    }}

在这里插入图片描述

范例:获取方法详细信息

package com.yootk.demo;import java.lang.reflect.Method;import java.lang.reflect.Modifier;import java.lang.reflect.Type;class Book {       public void read() throws RuntimeException {   }}public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           Class<?> clazz = Class.forName("com.yootk.demo.Book");        Method methods [] = clazz.getMethods() ;        for (Method method : methods) {               System.out.print(Modifier.toString(method.getModifiers()) + " "); // 获取方法修饰符            System.out.print(method.getGenericReturnType().getTypeName() + " "); // 获取返回值类型            System.out.print(method.getName() + "("); // 获取方法名称            Type[] parameterTypes = method.getGenericParameterTypes();// 获取方法参数信息            for (int x = 0 ; x < parameterTypes.length ; x ++) {                   System.out.print(parameterTypes[x].getTypeName() + " arg" + x);                if (x < parameterTypes.length - 1) {       // 后面还有其他参数                    System.out.print(", ");                }            }            System.out.print(") ");            Type[] exceptions = method.getGenericExceptionTypes() ; // 获取所抛出的全部异常信息            if (exceptions.length > 0) {       // 有异常抛出                System.out.print("throws "); // 输出throws信息                for (int x = 0; x < exceptions.length; x++) {                       System.out.print(exceptions[x].getTypeName());                    if (x < exceptions.length - 1) {                           System.out.print(", ");                    }                }            }            System.out.println(); // 换行        }    }}

根据方法名调用方法

package com.yootk.demo;import java.lang.reflect.Method;class Book {       private String title ;    public void setTitle(String title) {           this.title = title;    }    public String getTitle() {           return title;    }}public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           String fieldName = "title" ; // 明确给出了成员的属性名称        String fieldValue = "Java从入门到项目实战" ; // 成员属性的内容        Class<?> clazz = Class.forName("com.yootk.demo.Book");        // 1、如果要想通过Book类实现属性的操作,那么首先一定要获取Book类的对象        Object object = clazz.getDeclaredConstructor().newInstance() ; // 反射对象实例化        // 2、要找到指定调用的setter,setTitle()方法的参数类型为String        Method setMethod = clazz.getMethod("set" + initcap(fieldName), String.class) ;        // 3、利用反射结合对象实例(不是具体的Book类,而是Object类型)同时传入所需要的参数        setMethod.invoke(object, fieldValue) ; // 等价于“book类的对象.setTitle(fieldValue)”        // 4、找到getter方法,getter方法没有参数类型        Method getMethod = clazz.getMethod("get" + initcap(fieldName)) ;        // 5、通过反射获取getter方法的返回值        Object value = getMethod.invoke(object) ;// 等价于“book类对象.getTitle()”        System.out.println(value);    }    public static String initcap(String str) {           if (str == null || "".equals(str)) {               return str ;        }        if (str.length() == 1) {               return str.toUpperCase() ;        } else {               return str.substring(0, 1).toUpperCase() + str.substring(1) ;        }    }}

调用成员属性

package com.yootk.demo;import java.lang.reflect.Field;interface IBook {       public static final String FLAG = "沐言优拓:www.yootk.com" ;}abstract class AbstractBook implements IBook {       protected String type = "编程教育类图书" ;    private String company = "沐言科技软件学院" ;}class ProgramBook extends AbstractBook {       private String title ; // 图书名称}public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           Class<?> clazz = Class.forName("com.yootk.demo.ProgramBook") ; // 获取操作类        {               System.out.println("----------- getFields()执行结果 ------------");            for (Field field : clazz.getFields()) {    // 获取所有的成员                System.out.println("【继承来的public成员】" + field);            }        }        {               System.out.println("----------- getDeclaredFields()执行结果 ------------");            for (Field field : clazz.getDeclaredFields()) {    // 获取所有的成员                System.out.println("【本类定义的成员】" + field);            }        }    }}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

Unsafe工具类

在这里插入图片描述
在这里插入图片描述

获取Unsafe对象

package com.yootk.demo;import sun.misc.Unsafe;import java.lang.reflect.Field;public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe") ; // 通过反射获取成员        unsafeField.setAccessible(true); // 取消封装        Unsafe unsafe = (Unsafe) unsafeField.get(null) ; // 获取UnSafe对象        System.out.println(unsafe);    }}

范例:通过Unsafe类绕过JVM的对象管理机制实现方法调用

package com.yootk.demo;import sun.misc.Unsafe;import java.lang.reflect.Field;class Singleton {       private Singleton() {           System.out.println("【Singleton】实例化类对象");    }    public void print() {           System.out.println("李兴华编程训练营:yootk.ke.qq.com");    }}public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe") ; // 通过反射获取成员        unsafeField.setAccessible(true); // 取消封装        Unsafe unsafe = (Unsafe) unsafeField.get(null) ; // 获取UnSafe对象        Singleton singleton = (Singleton) unsafe.allocateInstance(Singleton.class) ; // 获取对象实例        singleton.print();    }}

ClassLoader

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.yootk.demo;public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           String message = "www.yootk.com" ; // 字符串,为系统类        System.out.println(message.getClass().getClassLoader());    }}

在这里插入图片描述

package com.yootk.demo;class Book {   }public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           Class<?> clazz = Book.class ; // 获得自定义类的Class对象        System.out.println(clazz.getClassLoader());        System.out.println(clazz.getClassLoader().getParent());        System.out.println(clazz.getClassLoader().getParent().getParent()); // Bootstrap    }}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

自定义ClassLoader

在这里插入图片描述

自定义类加载器

package com.yootk.util;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.InputStream;// 如果要想进行加载器的创建则必须继承自“ClassLoader”父类,并且依据方法进行调用public class FileClassLoader extends ClassLoader {    // 创建一个专属的文件加载器    // 定义要加载的字节码文件所处的绝对路径,必须通过File进行路径的拼凑    private static final String CLASS_FILE_PATH = "H:" + File.separator + "Message.class";    // 此时自定义了一个类加载的方法,这个类加载的方法一定不要重名    public Class<?> loadData(String className) throws Exception {           byte data [] = this.loadFileClassData() ; // 加载要使用的类文件        if (data != null) {    // 类信息已经成功的进行了加载            return super.defineClass(className, data, 0, data.length);        }        return null ;    }    // 自定义一个新的方法,将根据给定的文件路径进行加载,为了简化没有进行严格的异常控制    private byte[] loadFileClassData() throws Exception {           // 获取要加载文件的二进制字节输入流对象        InputStream input = new FileInputStream(new File(CLASS_FILE_PATH)) ;        // 最终需要将所有的数据保存在内存之中,并且要利用字节数组返回        ByteArrayOutputStream bos = new ByteArrayOutputStream() ; // 内存输出流        input.transferTo(bos) ; // 轻松的解决字节数据的读取        byte data [] = bos.toByteArray() ; // 获取全部的Class文件数据        input.close();        bos.close();        return data ; // 返回二进制数据    }}
package com.yootk.demo;import com.yootk.util.FileClassLoader;import java.lang.reflect.Method;public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           FileClassLoader fileClassLoader = new FileClassLoader() ;// 实例化自定义类加载器        Class<?> clazz = fileClassLoader.loadData("com.yootk.util.Message") ; // 加载类        Object messageObject = clazz.getDeclaredConstructor().newInstance() ;        Method method = clazz.getMethod("echo", String.class) ; // 获取echo()方法对象        System.out.println(method.invoke(messageObject, "沐言优拓:www.yootk.com"));    }}

自定义网络类加载器

在这里插入图片描述

范例:开发一个网络服务器

范例:开发一个网络加载器

package com.yootk.util;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.InputStream;import java.net.Socket;// 如果要想进行加载器的创建则必须继承自“ClassLoader”父类,并且依据方法进行调用public class NetClassLoader extends ClassLoader {    // 创建一个专属的文件加载器    // 此时需要通过特定的网络服务器进行类的加载,那么就必须明确的定义出服务器的地址以及连接端口    private static final String SERVER_HOST = "localhost" ; // 直接进行本机网络服务访问    private static final int SERVER_PORT = 9999 ; // 服务器的连接端口    // 此时自定义了一个类加载的方法,这个类加载的方法一定不要重名    public Class<?> loadData(String className) throws Exception {           byte data [] = this.loadFileClassData() ; // 加载要使用的类文件        if (data != null) {    // 类信息已经成功的进行了加载            return super.defineClass(className, data, 0, data.length);        }        return null ;    }    // 自定义一个新的方法,将根据给定的文件路径进行加载,为了简化没有进行严格的异常控制    private byte[] loadFileClassData() throws Exception {           // 获取要加载文件的二进制字节输入流对象        Socket client = new Socket(SERVER_HOST, SERVER_PORT) ; // 进行网络服务器的连接        // 获取网络服务器响应给客户端的字节输入流        InputStream input = client.getInputStream() ; // 网络输入流        // 最终需要将所有的数据保存在内存之中,并且要利用字节数组返回        ByteArrayOutputStream bos = new ByteArrayOutputStream() ; // 内存输出流        input.transferTo(bos) ; // 轻松的解决字节数据的读取        byte data [] = bos.toByteArray() ; // 获取全部的Class文件数据        client.shutdownInput(); // 等待网络数据接收完毕后关闭连接        input.close();        bos.close();        return data ; // 返回二进制数据    }}

反射机制与代理设计模式

静态代理设计模式

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

动态代理设计模式

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
示例代码:

package com.itkey.javareview.温故知新.反射机制;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;interface IMessage{    //核心业务接口    public String echo(String msg);}class MessageImpl implements IMessage{       @Override    public String echo(String msg) {           return "【ECHO】" + msg;    }}class ServerProxy implements InvocationHandler{     //此为公共的代理实现类    private Object target;      //核心业务对象    /**     * 由于动态代理设计模式需要保存有真实业务的主题对象,那么这个时候就需要将真实业务对象传递到本方法之中     * 同时基于proxy系统类,动态创建有一个代理业务类对象     * @param target 要绑定的真实业务对象     * @return 系统生成的代理类对象     */    public Object bind(Object target){         //保存真实业务对象        this.target = target;        //获取真实业务主题所在类对应的类加载器,因为需要分析真实业务主题接口所拥有的方法,才可以构建动态子类        // 所有动态代理者阳基于接口中的设计应用,那么此时就要获取全部的接口信息        // 当前的类为InvocationHandler接口子类,所以使用this描述的是本接口的实例化对象        return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);    }    @Override    public Object invoke(Object o, Method method, Object[] args) throws Throwable {           Object returnValue = null;        if(this.connect()){               returnValue = method.invoke(this.target,args);            this.close();        }        return returnValue;    }    public boolean connect(){          //代理方法        System.out.println("【代理业务】连接远程服务器,建立消息发磅通道");        return true;    }    public void close(){           System.out.println("【代理业务】信息发送完毕,关闭远程消息通道");    }}public class jdk动态代理机制 {       public static void main(String[] args) {           IMessage messageObject = (IMessage) new ServerProxy().bind(new MessageImpl());      //获取代理对象        System.out.println(messageObject.echo("动态代理如此简单"));    }}

CGLB实现动态代理

在这里插入图片描述

https://mvnrepository.com/4package com.yootk.demo;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;class Message {    // 不需要使用到接口    public String echo(String msg) {           return "【ECHO】" + msg;    }}class ServerProxy implements MethodInterceptor {      // 【CGLIB】方法拦截器    private Object target ; // 真实业务主题对象    public ServerProxy(Object target) {           this.target = target ;    }    public boolean connect() {    // 代理方法        System.out.println("【代理业务】连接远程服务器,建立消息发送通道。");        return true ;    }    public void close() {           System.out.println("【代理业务】信息发送完毕,关闭远程消息通道。");    }    @Override    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {           Object returnValue = null ; // 返回值        if (this.connect()) {               returnValue = method.invoke(this.target, objects) ; // 反射调用方法            this.close(); // 关闭服务器连接        }        return returnValue;    }}public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           Message target = new Message() ; // 核心业务对象        Enhancer enhancer = new Enhancer();// 代理控制类        enhancer.setSuperclass(target.getClass()); // 模拟一个公共父类        enhancer.setCallback(new ServerProxy(target)); // 配置代理功能        Message proxy = (Message) enhancer.create() ; // 创建代理对象        System.out.println(proxy.echo("沐言优拓:www.yootk.com"));    }}

反射获取Annotation信息

在这里插入图片描述

package com.yootk.demo;import java.lang.annotation.Annotation;import java.lang.reflect.Method;@FunctionalInterface // 函数式接口定义@Deprecated(since = "1.1") // 此接口不推荐使用interface IMessage {       // 定义一个接口    public String echo(String msg) ;}@Deprecated(since = "3.0")class MessageImpl implements IMessage {       @Override    public String echo(String msg) {           return "【ECHO】" + msg ;    }}public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           {               System.out.println("---------- 获取IMessage接口上的注解信息 ----------");            Class<?> clazz = IMessage.class ; // 获取接口的Class对象实例            for (Annotation annotation : clazz.getAnnotations()) {                   System.out.println(annotation);            }        }        {               System.out.println("---------- 获取MesageImpl子类上的注解信息 ----------");            Class<?> clazz = MessageImpl.class ; // 获取接口的Class对象实例            for (Annotation annotation : clazz.getAnnotations()) {                   System.out.println(annotation);            }        }        {               System.out.println("---------- 获取MesageImpl.echo()方法上的注解信息 ----------");            Class<?> clazz = MessageImpl.class ; // 获取接口的Class对象实例            Method method = clazz.getDeclaredMethod("echo", String.class) ;            for (Annotation annotation : method.getAnnotations()) {                   System.out.println(annotation);            }        }    }}

自定义Annotation

在这里插入图片描述
在这里插入图片描述

package com.yootk.demo;import java.lang.annotation.Annotation;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.reflect.Method;@Retention(RetentionPolicy.RUNTIME) // 在当前执行的时候此Annotation生效@interface Action {    // 自定义了一个Annotation    public String title() ; // 描述的是Annotation中的属性    public String value() ; // value是一个重要的标记}@Action(title = "沐言优拓:www.yootk.com", value = "李兴华编程训练营:yootk.ke.qq.com")class Message {       public String echo(String msg) {           return "【ECHO】" + msg ;    }}public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           {               System.out.println("---------- 获取IMessage接口上的注解信息 ----------");            Class<?> clazz = Message.class ; // 获取接口的Class对象实例            for (Annotation annotation : clazz.getAnnotations()) {                   System.out.println(annotation);            }        }    }}

在这里插入图片描述
在这里插入图片描述

Annotation整合工厂设计模式

在这里插入图片描述

在这里插入图片描述

package com.yootk.demo;import java.lang.annotation.*;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;@Target({   ElementType.TYPE}) // 此注解可以应用在类定义上@Retention(RetentionPolicy.RUNTIME) // 在当前执行的时候此Annotation生效@interface Action {    // 自定义了一个Annotation    public String value() ; // value可以避免编写变量名称}@Target({   ElementType.CONSTRUCTOR}) // 此注解可以应用在类定义上@Retention(RetentionPolicy.RUNTIME) // 在当前执行的时候此Annotation生效@interface Instance {    // 实现实例化对象控制的类型    public String value() ; // value可以避免编写变量名称}interface IChannel extends AutoCloseable {       public boolean build() ; // 建立通道}class InternetChannel implements IChannel {       @Override    public boolean build() {           System.out.println("【InternetChannel】建立互联网通讯通道。");        return true;    }    @Override    public void close() throws Exception {           System.out.println("【InternetChannel】关闭互联网通讯通道。");    }}class RadioChannel implements IChannel {       @Override    public boolean build() {           System.out.println("【RadioChannel】建立无线电通讯通道。");        return true;    }    @Override    public void close() throws Exception {           System.out.println("【RadioChannel】关闭无线电通讯通道。");    }}class Factory {    // 编写工厂类    private Factory() {   }    public static <T> T getInstance(String className) {           try {      // 实现一个泛型工厂类            return (T) Class.forName(className).getDeclaredConstructor().newInstance();        } catch (Exception e) {               return null ;        }    }}@Action("com.yootk.demo.RadioChannel") // 通过注解配置了当前Message类所使用的通道信息class Message {    // 进行消息的发送处理    private IChannel channel ; // 如果需要发送消息就必须提供通道    @Instance("com.yootk.demo.Factory")    public Message() {     // 构造方法        try {   // 获取指定的注解配置的信息            Action actionAnnotation = super.getClass().getAnnotation(Action.class) ; // 获取类上的Annotation            Instance instanceAnnotation = super.getClass().getConstructor().getAnnotation(Instance.class); // 获取构造方法上的指定构造            String factoryClassName = instanceAnnotation.value() ;            Class factoryClazz = Class.forName(factoryClassName) ;            this.channel = (IChannel) factoryClazz.getMethod("getInstance", String.class).invoke(null, actionAnnotation.value()) ;        } catch (Exception e) {   }    }    public String echo(String msg) throws Exception {           String echoMessage = "〖ERROR〗消息发送失败!" ;        if (this.channel.build()) {    // 通道创建成功            echoMessage = "【ECHO】" + msg ; // 创建回应信息            this.channel.close();        }        return echoMessage ;    }}public class YootkDemo {       // 李兴华编程训练营:yootk.ke.qq.com    public static void main(String[] args) throws Exception {           System.out.println(new Message().echo("www.yootk.com"));    }}

反射机制与简单Java类

在这里插入图片描述

传统类属性赋值的弊端

在这里插入图片描述
在这里插入图片描述

属性的自动赋值实现思路

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

单级属性赋值

在这里插入图片描述
在这里插入图片描述

属性类型转换

在这里插入图片描述
在这里插入图片描述

级联对象的实例化

上一篇:Java温故而知新-类集
下一篇:SQLcl使用vim编辑sql

发表评论

最新留言

关注你微信了!
[***.104.42.241]2025年03月23日 05时38分34秒