认识反射机制
正
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);
}
}
反射机制与对象实例化
1、
package 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() ;
}
}
2、
package 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的时候依然可以正常使用
}
}
3、
package 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() ;
}
}
4、
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 {
Class<?> bookClazz = Class.forName("com.yootk.demo.Book") ; // 实例化Book类的对象
// newInstance()返回的是一个Object类型,那么就必须进行对象的强制向下转型
Book book = (Book) bookClazz.getDeclaredConstructor().newInstance() ;
book.read();
}
}
5、
package 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());
}
}
6、
package 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();
}
}
7、
package 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();
}
}
8、
package 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);
}
}
}
9、
package 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();
}
}
}
10、
package 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();
}
}
}
11、
package 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/
4、
package 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类
传统类属性赋值的弊端
属性的自动赋值实现思路
单级属性赋值
属性类型转换