Java学习路线-29:反射机制与应用案例

举报
彭世瑜 发表于 2021/08/14 00:29:20 2021/08/14
【摘要】 第21 章 : 认识反射机制 99 反射机制简介 Java的精髓所在 动态获取信息以及动态调用对象方法的功能 所有技术实现的目标只有一点:重用性 正:类 -> 实例对象 反:实例对象 -> 类 找到对象的根源 Object.getClass() 1 100 Class类对象的三种实例化模式 public final class Class&...

第21 章 : 认识反射机制

99 反射机制简介

Java的精髓所在
动态获取信息以及动态调用对象方法的功能

所有技术实现的目标只有一点:重用性

正:类 -> 实例对象
反:实例对象 -> 类

找到对象的根源

Object.getClass() 

  
 
  • 1

100 Class类对象的三种实例化模式

public final class Class<T> implements java.io.Serializable, GenericDeclaration, Type, AnnotatedElement

  
 
  • 1
  • 2
  • 3
  • 4

要实例化的类

class Person{}

  
 
  • 1

1、Object类支持
Object类可以根据实例化对象获取Class对象

缺点:
如果想获得类对象,则必须产生指定类对象后才能获得

Person person = new Person();
Class cls = person.getClass();

System.out.println(cls.getName());
// Person

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

2、JVM直接支持
采用类.class 直接实例化
如果要采用这种模式,则必须导入程序所对应开发包

Class cls = Person.class;

System.out.println(cls.getName());
// Person

  
 
  • 1
  • 2
  • 3
  • 4

3、Class类支持
Class类中提供了static方法

public static Class<?> forName(String className)

  
 
  • 1

特点:
直接使用字符串形式定义要使用的类型,
程序不需要编写import,不存在则抛出异常

Class cls = Class.forName("Person");

System.out.println(cls.getName());
// Person

  
 
  • 1
  • 2
  • 3
  • 4

第22 章 : 反射应用案例

101 反射实例化对象

获取Class对象意义:
Class对象提供有一个对象的反射实例化方法

1、JDK<1.9

public T newInstance()
// 等价于关键字new, 只能调用无参构造 JDK>=1.9之后弃用

  
 
  • 1
  • 2

示例

Class cls = Class.forName("Person");
System.out.println(cls.newInstance());
// Person@2503dbd3

  
 
  • 1
  • 2
  • 3

2、JDK>=1.9

public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)

  
 
  • 1

示例

Class cls = Class.forName("Person");
System.out.println(cls.getDeclaredConstructor().newInstance());
// Person@2503dbd3

  
 
  • 1
  • 2
  • 3

任何情况下如果要实例化对象则一定要调用类中的构造方法

102 反射与工厂设计模式

工厂设计模式:
通过工厂类获取指定接口实例化对象

接口的主要作用是为不同的层提供有一个操作的标准
如果直接将一个子类设置为接口实例化操作,那么一定会有耦合
工厂设计模式解决子类与客户端的耦合问题

1、静态工厂设计模式
如果子类增加,工厂类一定要做出修改
解决一个子类实例化

IMessage -NetMessage -CloudMessage

Factory // 通过传入的参数获取子类

Client 

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
interface IMessage { public void send(String message);
}

class Message implements IMessage { @Override public void send(String message) { System.out.println("发送: " + message); }
}

class Factory { private Factory() { } public static IMessage getInstance(String className) { if ("Message".equalsIgnoreCase(className)) { return new Message(); } return null; }
}

public class Demo { public static void main(String[] args) { IMessage message = Factory.getInstance("message"); message.send("nihao"); }
}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

2、利用反射实现工厂设计模式
解决一个接口多个子类实例化

修改工厂类代码

class Factory { private Factory() { } public static IMessage getInstance(String className) { IMessage message = null; try { message = (IMessage)Class.forName(className).getDeclaredConstructor().newInstance(); } catch (Exception e) { e.printStackTrace(); } return message; }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

3、泛型反射实现工厂设计模式
解决所有接口子类实例化


class Factory { private Factory() { } public static <T> T getInstance(String className, Class<T> clazz) { T instance = null; try { instance = (T)Class.forName(className).getDeclaredConstructor().newInstance(); } catch (Exception e) { e.printStackTrace(); } return instance; }
}

public class Demo { public static void main(String[] args) { IMessage message = Factory.getInstance("Message", IMessage.class); message.send("nihao"); }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

103 反射与单例设计模式

单例设计模式:
类的构造函数私有化,通过static方法获取实例化对象
-懒汉式
-饿汉式

class Singleton{ private static Singleton instance = null; private Singleton() { } public static Singleton getInstance(){ if(instance == null){ instance = new Singleton(); } return instance; } public void print(){ System.out.println("Singleton"); }
}

class Demo{ public static void main(String[] args) { Singleton instance = Singleton.getInstance(); instance.print(); }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

多线程下执行,产生多个实例化对象

class Singleton{ private static Singleton instance = null; private Singleton() { System.out.println("Singleton " + Thread.currentThread().getName()); } public static Singleton getInstance(){ if(instance == null){ instance = new Singleton(); } return instance; } public void print(){ System.out.println("Singleton print"); }
}

class Demo{ public static void main(String[] args) { for (int i = 0; i < 3; i++) { new Thread(()->{ Singleton instance = Singleton.getInstance(); instance.print(); }, "instance" + i).start(); } /** * 输出结果 * Singleton instance0 * Singleton instance1 * Singleton print * Singleton instance2 * Singleton print * Singleton print */ }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

修改为同步处理

class Singleton{ // volatile 不使用副本 private static volatile Singleton instance = null; private Singleton() { System.out.println("Singleton " + Thread.currentThread().getName()); } // synchronized不在函数上加,而是在内部代码块加,提高执行效率 public static Singleton getInstance(){ if(instance == null){ synchronized (Singleton.class){ if(instance == null) { instance = new Singleton(); } } } return instance; } public void print(){ System.out.println("Singleton print"); }
}

class Demo{ public static void main(String[] args) { for (int i = 0; i < 3; i++) { new Thread(()->{ Singleton instance = Singleton.getInstance(); instance.print(); }, "instance" + i).start(); } /** * 输出结果 * Singleton instance1 * Singleton print * Singleton print * Singleton print */ }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

面试题:单例设计模式
1、实现饿汉式单例设计模式,构造函数私有化
2、Java中用到单例设计模式的类:
Runtime, Pattern, Spring框架
3、懒汉式单例设计模式的问题

文章来源: pengshiyu.blog.csdn.net,作者:彭世瑜,版权归原作者所有,如需转载,请联系作者。

原文链接:pengshiyu.blog.csdn.net/article/details/103789045

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。