4.4静态域与静态方法
4.4.1静态域
1静态域与实例域的区别:静态域独立于实例存在,它属于类,不属于对象;而实例域属于对象。(创建100个类对象,有100个实例域,但是只有一个静态域)
4.4.2 静态常量
1常用的静态常量:MATH.PI,System.out,
2静态常量可以设置为public类型的, 普通域则不可以,因为静态常量已经被设为final的了。
3ps:本地方法可以绕过java语言的存取控制机制(如setOut方法,它可以修改final变量的值)
4.4.3 静态方法
1静态方法不能访问实例域,因为他不能操作对象(不能向对象实施操作的方法),但可以访问自身类中的静态域,可以通过类名来调用这个方法。
2不建议静态方法省略关键字static来访问自身的静态域
3使用静态方法的两种情况:
-
一个方法不需要访问对象状态,其所需的参数都是通过显示参数提供(静态方法没有隐式参数,故没有this参数的方法)(
Math.pow
)
-
一个方法只需要访问类的静态域(Employee.getNextId();)
4.4.4 工厂方法(静态方法的常见用途)
NumberFormat类不利用构造器来构造对象的原因:
a 无法命名构造器。构造器的名字必须与类名相同
b当使用构造器时,无法改变所构造的对象类型
4.4.5 main方法
main方法也是一个静态方法,main方法不对任何对象进行操作,静态的main方法将执行并创建所需要的对象
每一个类可以有一个main方法,用于对类进行单元测试
这里有个典型例题:
public class Employee {
private static int nextId = 1;//定义静态域
private String name;
private double salary;
private int id;
public Employee(String n,double s) {
name = n;
salary = s;
id = 0;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public int getId() {
return id;
}
public void setId() {
id = nextId;
nextId++;
}
public static int getNextId() {
return nextId;
}
public static void main(String[] args) {
Employee e = new Employee("harry",10000);
System.out.println(e.getName()+" "+e.getSalary()+" "+getNextId());
}
}
public class StaticTest {
public static void main(String[] args) {
//
Employee[] staff = new Employee[3];
staff[0] = new Employee("tom", 2000);
staff[1] = new Employee("dick", 40000);
staff[2] = new Employee("harry", 39000);
for (Employee e : staff) {
e.setId();
System.out.println(e.getName()+" "+e.getId()+" "+e.getSalary());
}
int n = Employee.getNextId();
System.out.println(n);
}
}
该例题使用了静态域,静态方法,比较典型,可以记住
4.5方法参数
方法参数分成两类:基本数据类型
对象引用
一个方法不可能修改一个基本数据类型的参数;
一个方法可以改变一个对象参数的状态;
一个方法不能让对象参数引用一个新的对象
4.6对象构造
4.6.1重载
1方法的签名:方法名+参数类型,返回类型不是方法签名的一部分
2Java允许重载任何方法,不只是构造器方法
4.6.2默认域初始化
如果没有初始化类中的域,将会被自动初始化为默认值,不推荐使用
4.6.3无参数的构造器
如果在编写一个类时没有编写构造器,那么系统就会提供一个无参构造器,将所有的实例域设置为默认值
如果类中提供了至少一个构造器,但没有提供无参数的构造器,则在构造对象时如果没有提供参数就会视为不合法(仅当类没有提供任何构造器时,系统才会提供一个默认的构造器)
4.6.4 显式初始化
初始值不一定是常量值,也可以通过调用方法对域进行初始化
class Employee{
private static int nextId;
private int id = assignId();
...
private static int assignId(){
int r = nextId;
nextId++;
return r;
}
}
4.6.5 参数名
两种方法:1加上前缀来区分实例域与参数
public Employee(String aName,double aSalary){
name = aName;
salary = aSalary;
}
2使用this.来访问实例域
public Employee(String name,double salary){
this.name = name;
this.salary = salary;
}
4.6.6调用另一个构造器
用this来调用同一个类的另一个构造器
好处:对公共的构造器代码部分值编写一次即可
4.6.7 初始化块
静态域初始化块在类第一次加载的时候就会进行
4.6.8 对象析构和finalize方法
java中不支持析构器,因为java中有自动的垃圾回收器,不需要人工回收内存
可以为任何一个类finalize方法,该方法在垃圾回收器清除对象之前调用