1.static
static可以修饰变量和函数。
static修饰的变量叫类变量,未被static修饰的变量叫实例变量。
类变量共同属于所有实例,被所有实例共享,可以通过类名来访问,如Student.name,也可以通过实例来访问,如s.name。
public class User{
public static num; //类变量,被共享
public User(){
num++; //这个类每被创建一次,num就加1,num数代表类被创建了几次
}
}
而实例变量分别属于不同的实例,只能通过实例对象来访问。
static修饰的方法叫类方法,可以直接通过类名来访问:Student.printScore(),也可以通过实例对象来访问,s.printScore()。更加推荐使用类名来访问。
原因如下:
类方法最常见于工具方法,直接通过类名来调用这个类方法,而不需要额外创建实例对象然后调用实例方法(因为会浪费内存)。
PS:工具类里可以把构造器私有化,如下,这样可以使这个类只能被调用方法,不能被实例化,更标准。
private XXUtil(){
}
而未被static修饰的方法实例方法,只能被实例对象来访问。
注意事项:
1.类方法中可以直接访问类变量/其他类方法,不可以直接访问实例对象/方法。
2.实例方法中可以直接访问类变量/方法,也可以直接访问实例变量/其他实例方法。
3.实例方法中可以直接出现this关键字并进行赋值,但类方法中不可以(this专属于实例)。
2.单例
单例是一种设计模式,对于设计模式我个人觉得两点最重要:
- 解决什么问题?
- 怎么写?
单例意味着这个类只能被实例化一次,具体的应用场景比如任务管理器之类。
单例的创建分为以下三个步骤:
- 私有化构造器,以防止这个类可以被多次实例化
- 申明或直接赋值给当前类的实例化对象(用static修饰,这样这个对象只有一个且被共享)
- 创建一个函数,返回对象为单例类的实例化对象
//法一:
public class SingleDemo {
private static SingleDemo sd = new SingleDemo(); //2.直接赋值创建好这个单例类的实例化对象
private SingleDemo(){ //1.私有化构造器
}
//返回对象为singledemo这个实例
public static SingleDemo getObject(){ //3.调用函数,函数返回一个实例对象
return sd;
}
}
//法二:
public class SingleDemo {
private static SingleDemo sd; //2.申明这个单例类的实例化对象,但暂时不赋值
private SingleDemo(){ //1.私有化构造器
}
//返回对象为singledemo这个实例
public static SingleDemo getObject(){ //3.调用函数,函数返回一个实例对象
if(sd == null){
sd = new SingleDemo(); //在这边才正式给这个实例化对象赋值
}
return sd;
}
}
3.final
final可以修饰类/方法/变量
- final修饰类
当用final修饰一个类时,表明这个类不能被继承。
在使用final修饰类的时候,要注意谨慎选择,除非这个类真的在以后不会用来继承或者出于安全的考虑,尽量不要将类设计为final类。 - final修饰方法
使用final方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升。在最近的Java版本中,不需要使用final方法进行这些优化了。 - final 修饰变量
修饰变量是final用得最多的地方:
对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。
虽然被final修饰之后不能再指向其他变量了,但还是可以修改变量引用的对象的具体内容,如下:
public class Test {
public static void main(String[] args) {
final MyClass myClass = new MyClass();
System.out.println(++myClass.i);
}
}
class MyClass {
public int i = 0;
}