Java温故而知新-反射机制

认识反射机制

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类

在这里插入图片描述

传统类属性赋值的弊端

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

属性的自动赋值实现思路

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

单级属性赋值

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

属性类型转换

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

级联对象的实例化

猜你喜欢

转载自blog.csdn.net/lxyoucan/article/details/115019765