java 反射 单例类_单例模式(4种),反射

本文详细介绍了Java中四种单例模式的实现:饿汉式、懒汉式、线程安全的懒汉式和双重验证懒汉式,并探讨了反射技术在创建对象和访问私有成员时的应用。

单例模式:

这种模式叫做 “饿汉式” 单例设计模式

步骤:

1:私有的无参构造方法

2:内部定义一个 私有的 静态的 类型本身的对象,并且直接使用无参构造初始化

3:提供一个公开的,静态的,成员方法,返回第二步中创建的对象

默认自带一种好处,线程安全的

public class MyRuntime {

private String name;

private int age;

private static MyRuntime rt = new MyRuntime();

// 提供一个private的构造方法,来抑制jvm自动添加无参构造

private MyRuntime() {

}

// 定义一个public的成员方法,来返回rt这个成员变量

public static MyRuntime getInstance() {

return rt;

}

}

“懒汉式” 单例模式

步骤:

1:私有的无参构造方法

2:内部定义一个 私有的 静态的 类型本身的对象,设置初始值为null

3:提供一个公开的,静态的,成员方法,先给第二步创建的对象实例化,然后再返回

lazy load 延迟加载

public class MyRuntime2 {

// 第二步:

private static MyRuntime2 rt = null;

// 第一步:

private MyRuntime2() {

}

// 第三步:

public static MyRuntime2 getInstance() {

if (rt == null) {

rt = new MyRuntime2();

}

return rt;

}

}

线程安全的 “懒汉式” 单例模式

步骤:

1:私有的无参构造方法

2:内部定义一个 私有的 静态的 类型本身的对象,设置初始值为null

3:提供一个公开的,静态的,成员方法,先给第二步创建的对象实例化,然后再返回

“懒汉式” 单例模式

lazy load 延迟加载

public class MyRuntime3 {

// 第二步:

private static MyRuntime3 rt = null;

// 第一步:

private MyRuntime3() {

}

// 第三步: 对象锁 MyRuntime3.class

public static synchronized MyRuntime3 getInstance() {

if (rt == null) {

rt = new MyRuntime3();

}

return rt;

}

}

双重验证 “懒汉式” 单例模式

步骤:

1:私有的无参构造方法

2:内部定义一个 私有的 静态的 类型本身的对象,设置初始值为null

3:提供一个公开的,静态的,成员方法,先给第二步创建的对象实例化,然后再返回

“懒汉式” 单例模式

lazy load 延迟加载

public class MyRuntime4 {

// 第二步:

private static volatile MyRuntime4 rt = null;

// volatile:修饰成员变量,是告诉jvm,别优化该成员变量对应的执行指令

// 第一步:

private MyRuntime4() {

}

// 第三步: 对象锁 MyRuntime4.class

public static MyRuntime4 getInstance() {

if (rt == null) {

synchronized (MyRuntime4.class) {

if (rt == null) {

rt = new MyRuntime4();

}

}

}

return rt;

}

}

Class类型

AAffA0nNPuCLAAAAAElFTkSuQmCC

反射:

是技术,一种方式,为了创建对象用的

访问对象成员(成员变量,成员方法)

传统方式创建对象

Student stu = new Student();

stu.getAge();

System.out.println(stu.toString());

新的方式,反射的方式创建对象

Class 类型:是所有的.class字节码文件的 抽象

类的定义:一组相关的属性和形为的集合

所有的.class 中都有 成员变量,都有构造方法,成员方法

java 创建了一个 新的类型 Class 来表示所有的.class 字节码

基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void

也表示为 Class 对象

Class 没有公共构造方法 .Class 的构造 是由jvm完成的

Class 类型的常用方法

static Class> forName(String className)

参数指定类的字符串表示形式(类的全名 = 包名 + 类)

// java.lang.ClassNotFoundException: Student

Class clazz = Class.forName("com.newedu.jb.day22.dp.Student");

拿到对象clazz 相当于拿到了 Student.class 的字节码文件

如何根据Class的对象Clazz,来创建Student类型的对象?

一个类中总是有 成员变量,构造方法,成员方法

将字节码 抽象为一个Class类型

将类的成员变量 抽象为一个Field类型

将类的构造方法 抽象为一个Constructor类型

将类的成员方法 抽象为一个Method类型

获取指定的构造方法

Constructor getConstructor(Class>... parameterTypes)

返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法

Class>... parameterTypes:是一个可变参数,也可以理解数组是一个Class数组

除了Class.forName(),我们还可以通过什么来获取Class对象呢?

第二种:类型名.class Student.class

第三种:对象名.getclass() stu.getClass()

Constructor c1 = clazz.getConstructor(String.class, int.class, String.class);

T newInstance(Object... initargs)

使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例

通过反射访问类中的私有成员

Class clazz = Class.forName("com.newedu.jb.day19.dp.Student");

// 通过getConstructor()方法只能获取public 的构造方法

// Constructor con = clazz.getConstructor(String.class,int.class);

// 如果想获取私有的构造方法 getDeclaredConstructor(Class>... parameterTypes)

Constructor con = clazz.getDeclaredConstructor(String.class, int.class);

// setAccessible(true); 设置成员的强制访问

IllegalAccessException - 如果此 Constructor 对象实施 Java 语言访问控制并且底层构造方法是不可访问的。

如果成员是私有的,默认情况是会抛出这个异常。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值