Java this,构造器,static,final,单例模式
this,构造器,static,final,单例模式
this关键字
-
在java中this是一个引用变量,即指向当前对象地址的引用(指针),→可以把this当作当前对象,便于更好的索引.
-
this()
实际是调用了当前对象的构造器 -
1. 引用当前对象的属性
- 当在方法中要访问当前对象的属性时,可以用this来区分局部变量与全局变量.若局部变量和全局变量同名,this指向的属性是全局变量
public class MyClass { private int value; public MyClass(int value) { this.value = value; // this.value引用的是成员变量value,而value是参数 } public void setValue(int value) { this.value = value; // 同样,this.value引用的是成员变量value } public int getValue() { return this.value; // 虽然这里不使用this也能访问value,但使用this可以增加代码的可读性 } }
-
- 调用当前对象的其他方法
- 在方法内部也可以用this来调用当前对象的其他方法,(包括构造方法)
public class MyClass { public MyClass() { this.initialize(); // 调用当前对象的initialize方法 } public void initialize() { // 初始化代码... } }
-
3.引用当前对象的构造方法
- this()可以在构造方法是调用同一个类的其他构造方法,但必须放在第一行,这样的好处是实现构造方法的重写与复用
public class MyClass { private int value; public MyClass() { this(0); // 调用带有单个参数的构造方法 } public MyClass(int value) { this.value = value; } }
-
- 在事件监听器中使用
当在事件监听器(如
ActionListener
)中需要引用触发事件的组件时,可以使用this
关键字(如果监听器是内部类并且需要引用外部类的实例)。 -
5.在匿名内部类中使用
在匿名内部类(如线程、事件监听器等)中,
this
关键字通常指向外部类的实例,而如果要引用匿名内部类的实例,则没有直接的this
引用,通常需要使用其他方式(如将匿名内部类的实例赋值给一个变量)。
构造器(构造函数)
-
是创建(new)对象时java会默认调用的方法,通常用给对象传递参数来赋值,
-
语法
- 构造函数没有返回值,没有void,int 等等
- 构造函数名必须与类名一致
- 在构造函数中要第一所传入的参数列表→非必须
-
默认构造器
权限修饰符 类名() { //初始化等功能.. }
-
带参构造器(常用)
权限修饰符 类名(数据类型 参数) { //初始化等功能.. }
注意点:
- 如果一个类中只有带参构造器,则默认的构造器就会被覆盖→消失,如果还有需要默认构造器,则需显示性定义
- 同一个类中的构造器可以相互调用,需要用this()来调用,this必须放在第一行→无参构造器托付有参构造器进行构造
public class Person {
private String name;
private int age;
// 无参构造函数
public Person() {
this("Unknown", 0); // 使用this()调用另一个构造函数
//通过this之间调用有参构造函数
}
// 带两个参数的构造函数
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 省略getter和setter方法...
public static void main(String[] args) {
Person unknownPerson = new Person(); // 调用无参构造函数,实际上会委托给带两个参数的构造函数
System.out.println("Name: " + unknownPerson.getName() + ", Age: " + unknownPerson.getAge());
Person knownPerson = new Person("John Doe", 30);
System.out.println("Name: " + knownPerson.getName() + ", Age: " + knownPerson.getAge());
}
}
- 在构造器中调用其他构造器,不会创建对象,只会初始化
public class Example {
private int x;
private String y;
// 第一个构造器,带有两个参数
public Example(int x, String y) {
this.x = x;
this.y = y;
System.out.println("Two-argument constructor called.");
}
// 第二个构造器,无参数,通过this()调用第一个构造器
public Example() {
this(10, "Default"); // 使用this()调用带有两个参数的构造器
System.out.println("No-argument constructor called.");
}
public static void main(String[] args) {
Example obj = new Example(); // 调用无参数构造器
}
}
static关键字
内存角度分析:当我们执行一个java文件时,java虚拟机会优先加载方法区中的内容,若遇到stati代码块,则立即运行.也就是说用static关键字修饰的内容在对象还未创建之前就被分配了内存空间,这也是我们为什么能够直接使用类名.方法或类名.变量名去调用类变量和类方法的原因,也是为什么我们不能在类方法中使用实例变量和普通方法的原因。
- static一般用来修饰成员变量或者函数
- 被static修饰的变量名叫类变量,方法叫类方法
- 被static关键字修饰的不需要去创建对象去调用,可以直接用类名.调用
- 作用:方便再没有创建对象的情况下来进行调用
简单理解为被static修饰的方法或变量是存放再方法区与类信息存放在一起
static比实例化对象先分配内存空间
final关键字
可用来修饰变量和成员方法以及类
final类
- 当final修饰类时,该类不可被继承.
final方法
- 当一个方法被final修饰时,该方法不可被覆盖→重写
- 应用场景:当你希望如果你希望某个方法的行为在整个类层次结构中保持一致,并且不希望被子类改变,那么你可以将其声明为
final
final变量
- 实例变量:当一个实例变量被修饰成final时,它只能在声明时或者构造方法中被赋值,且只能被赋值一次
- 静态变量:与实例变量情况相同,必须在声明或者静态语句块中被赋值,且只能赋值一次
- 局部变量:即方法中的变量,在声明时可以不要立即赋值,但使用前必须赋值
final参数
- 当一个方法的参数被final修饰时,在这个方法内部不可再被赋值
单例模式
单例模式:是一种设计模式,它确保一个类只能有一个实例,并提供一个全局访问的点来访问这唯一的实例对象, -这个模式在多线程环境和一些需要频繁创建和销毁对象但又希望限制这些对象数量的场景中特别有用-。
懒汉式→多线程下不安全,但节省内存空间
public class Singleton {
private static Singleton singleton; //
//通过声明一个静态的私有成员变量,并且在该类被加载到JVM时立即初始化这个变量
//我们创建了一个类的唯一实例。由于是静态的,这个实例与类本身相关联,而不是与类的某个特定实例相关联。
//同时,由于是私有的,外部代码无法直接访问这个变量,只能通过类提供的公共方法来获取它的值。
private Singleton() { //将构造函数设为私有化,目的是防止外部代码通过new创建实例对象
//它确保了除了类本身之外,没有其他代码能够实例化这个类
}
public static Singleton getSingleton() {
//外部代码可以获取到类的唯一实例。
由于这个方法是静态的,我们不需要先创建类的实例就可以调用它。
在方法内部,我们检查instance是否已经被初始化(即是否为null)。
如果是,我们就创建一个新的实例并赋值给singleton;如果不是(即singleton已经被初始化过),我们就直接返回singleton。
由于我们之前已经将构造函数设置为私有,并且singleton是静态的且只被初始化一次,
所以getSingleton()方法将始终返回同一个实例
if(singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
- 懒汉式单例模式在第一次被调用时才会创建实例,而不是在类加载时立即创建。
饿汉式→可以适用多线程,但消耗内存空间
public class Singleton2 {
Singleton2 类中的静态成员变量 singleton 在声明的同时就被初始化了。
这个初始化是在类被 JVM 加载到内存时发生的,且只会发生一次。
由于是静态的,所以不需要创建类的实例就可以访问它
private static Singleton2 singleton = new Singleton2();
private Singleton2() {
//使外部不能创建singleton
}
public static Singleton2 getSingleton() {
return singleton;
etSingleton() 是一个公共的静态方法,用于返回 Singleton2 类的单例实例。
由于 singleton 已经在类加载时初始化了,所以无论多少次调用 getSingleton(),
它都会返回同一个实例。
}
}
- 饿汉式即无论如何先创建一个实例化对象,接下来无论几次调用都返回同一个对象