Java学习路线-29:反射机制与应用案例
第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
- 点赞
- 收藏
- 关注作者
评论(0)