JAVA static 详解
在java中,static是完全避不开的一个问题,这也是众多面试官老生常谈的一个问题,所以对static的了解需要更进一步;
首先,你可以了解一下c++中static的作用和使用:c++中static的总结
static的用法
在《java核心技术卷一》中p112用了一章的一个小节讲解了“静态域和静态方法。
在《Java编程思想》P86页有这样一段话:
static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。这实际上正是static方法的主要用途。
1. 方便在没有创建对象的情况下来进行调用(方法/变量)。
很显然,被static关键字修饰的方法或者变量不需要依赖于对象来进行访问,只要类被加载了,就可以通过类名去进行访问。
static可以用来修饰类的成员方法、类的成员变量,另外可以编写static代码块来优化程序性能。
静态域
如果将域定义为static,每个类中只有一个这样的域。而每一个对象对于所有的实例域却都有自己的一份拷贝
1.这句话就说明声明了n个对象,
则非static的域有n个,而static的域只有一个
所有对象共享这一个static域
class Employee
{
//static的域
private static int nextId =1;
//非static的域
private int id;
}
静态常量
静态变量一般使用得少,而静态常量却使用得较多。
定义为静态常量的量可以不用创建对象来访问,可以通过类名直接调用
- Math中的PI常量
如Math类中的PI常量
public class Math
{
...
public static final double PI = 3.1415926538979323846;
...
}
在程序中调用这个常量就可以直接使用Math.PI来获得这个常量。
- 如果用static的常量,则创建多少个对象,就有多少个常量的拷贝,可以直接用类名.静态常量来获取这个常量
- 如果省略static,则每个对象都有自己的一份常量的拷贝,必须通过类创建的对象来获取这个常量
- System类中的out
public class System
{
...
public static final PrintStream out=...;
...
}
静态方法
使用静态方法的时候不需要创建任何对象,静态方法的语法格式是:类名.方法名();
如 Math.pow(x,a)
《java核心技术卷一》p114
在下面两种情况下使用静态方法:
- 一个方法不需要访问对象状态,其所需参数都是通过显示参数提供(例如:Math.pow)
- 一个方法只需要访问类的静态域(例如:Employee.getNextId)
这里需要注意到的是 参数分为两类
- 隐式参数:出现在方法名前的类名或者类对象
- 显式参数:位于方法名后面括号中的数值,可以理解为参数表
还有一点值得注意,就是java中的static含义和c++中的含义相同,即属于类且不属于类对象的变量和函数
工厂方法
这里有一个知识点要注意:
构造对象有两种方法:
- 构造器方法:如 Student stu =new Student(2018,“计算机”,2018xxx);
- 工厂方法:LocalDate today = LocalDate.now();
下面的情况:
NumberFormat currencyFormatter = NumberFormat,getCurrencyInstance();
NumberFormat percentFormatter = NumberFormat.getPercentInstance();
double x = 0.1;
System.out.println(currencyFormatter(x));//print $0.10
System.out.println(percentFormatter(x));//print 10%
这里使用工厂方法构造对象的原因:
- 无法命名构造器。构造器的名字必须与类名相同。但是有时候,希望将得到的货币实例和百分比实例采用不同的名字。
- 当使用构造器时,无法改变所构造的对象类型。而工厂方法将返回一个DecimalFormat的类对象,这是NumberFormat的子类。
main方法
这里有一个小技巧
可以在每一个类创建一个main方法,这是一个常用于对类进行单元测试的技巧
这时候如果要独立测试这个类,只需要执行
java 类名
如果是一个更大型应用程序的一部分,可以用下面的语句运行程序
java Application
这时候要测试类的main方法永远不会执行
static代码块
static关键字还有一个比较关键的作用就是 用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
为什么说static块可以用来优化程序性能,是因为它的特性:只会在类加载的时候执行一次。
具体内容可以参看下面这位大牛的博客:传送门