静态字段和静态方法
静态字段(类字段)
如果将一个字段定义为static,那么每个类只能有一个这样的字段
上面这句话的意思,可以通过下面的例子来理解
class Employee{
private static nextId =1;
private int id;
}
现在,每个Employee对象都有自己的一个id,但是这个类的所有实例将共享一个nextId。也即是说,即使我们实例化1000哥Employee对象,那么id将有1000个,但是静态字段nextId始终都是只有一个。
注意,即使没有Employee对象,nextId也存在,它只属于类,不属于任何单个的对象,静态字段的“空间”是共享的,而实例字段在每个实例中都有自己的一个独立“空间”
不过要注意的是,因为“共享”的特性,所以静态字段要少用,一般可以用实例字段。
静态常量
静态变量用到比较少,但是静态常量用的还是听多的(用final修饰的变量将被设置成常量)
public class Math{
public static final double PI=3.1415926...
}
如果省略了static,那PI就是Math类的一个实例字段。
上面说尽量少用静态字段,但是静态常量却没有这个问题,因为他是常量
有一个东西没有补充的是,被static修饰的引用,是不需要先声明对象的,可以直接就用,就像是直接写Math.PI就可以,不需要对Math实例化再去使用。
静态方法
静态方法就是不需要在对象上执行的方法,例如Math的pow方法。
可以认为静态方法就是没有this参数的方法(在一个非静态方法中,this参数指这个方法的隐式参数)
注意,Employee上的静态方法不能访问id实例字段,因为它不能在对象上执行操作。当然,静态方法还是可以访问静态字段的。
public static int getNextId(){
return nextId;
}
int n = Employee.getNextId();
上面的语句还是被允许的。
对象也可以调用静态方法,但是,如果使用静态方法的时候,还是建议使用类名引用静态方法,这是为了避免对方法本身静态与否产生混淆,并且,静态方法的结果一般与实例化的对象也没有关系,因为他需要的所有参数都是显示参数提供的。
工厂方法
https://blog.csdn.net/qq_36629833/article/details/90764881
上面是java三种工厂模式的简单介绍
利用工厂方法构造对象,就是根据参数的不同来返回不同类的实例。
NumberFormat cu=NumberFormat.getCurrencyInstance();
NumberFormat cn=NumberFormat.getPercentInstance();
double x=0.1;
System.out.println(cu.format(x)+" "+cn.format(x));
就像上面的这几个语句一样,为什么不用构造器来完成这些操作呢,因为构造器的名字必须跟类名相同,但是这里有两个类名(分别得到货币和百分比)。
main方法
main方法也是一个静态方法(因为调用的时候它也不需要构造新的对象)
事实上,程序一开始的时候还没有任何的对象,静态的main方法将执行并构造程序所需要的对象。同时,每一个类都可以有一个main方法(不只是主类)。
main方法可以进行单元测试
public class StaticTest {
public static void main(String[] args) {
Employeetwice[] staff=new Employeetwice[3];
staff[0]=new Employeetwice("Tom",75000);
staff[1]=new Employeetwice("Dick",71000);
staff[2]=new Employeetwice("Harry",72000);
for(Employeetwice e:staff){
e.setId();
System.out.println("name="+e.getName()+",id"+e.getId()+",salary="+e.getSalary());
}
int n=Employeetwice.getNextId();
System.out.println("Next available id = "+n);
}
}
class Employeetwice{
private static int nextId=1;
private String name;
private double salary;
private int id;
public Employeetwice(String n,double s){
this.name=n;
this.salary=s;
this.id=0;
}
public String getName(){
return name;
}
public double getSalary(){
return salary;
}
public int getId(){
return id;
}
public void setId(){
this.id=nextId++;
}
public static int getNextId(){
return nextId;
}
public static void main(String[] args) {
var e=new Employeetwice("Herry",40000);
System.out.println(e.getName()+" "+e.getSalary());
}
}
上面的程序中,如果运行public标注的类的main方法,那么将得到下面的结果:
name=Tom,id1,salary=75000.0
name=Dick,id2,salary=71000.0
name=Harry,id3,salary=72000.0
Next available id = 4
而这个不是单元测试,如果我们想要单元测试呢?那可以用到Employeetwice类里的main方法,运行这个main,我们将得到下面的结果:
Herry 40000.0