初始化与清理

在C/C++中,许多错误都源于未初始化变量和未释放无用的内存,而在Java语言在试图解决这些不安全的问题。Java使用了构造器垃圾回收器来显示变量的初始化
和内存资源的自动释放。

构造器

每个类都有一个或若干个构造器,调用构造器是编译器的责任,因此程序员的任务就是让编译器知道该调用哪个构造器。构造器要注意一下几点:

  • 构造器的名称和类名完全相同

  • 没有返回值

  • 如果不写构造器,不代表没有,系统会添加无参的构造器

  • 如果定义了有参数的构造器,则一定要定义无参的构造器

方法重载

几个函数拥有相同的函数名,即函数重载了。区分重载的规则很简单,每个重载的方法都必须有一个独一无二的参数类型列表。注意,参数的顺序能够区分两个方法,
但是一般不建议这么做。另外,不能以返回值区分函数。

在Java中,基本类型能从“较小”的类型自动提升到“较大”的类型,因此有时即使参数类型不一致,也会被调用,例如:

1
2
3
4
5
6
void f(double i){
System.out.println(i);
}
int i = 4;
f(i)

this指针

如果你想在某个方法内获得调用当前方法的对象,就能使用this指针,它表示调用方法那个对象的引用。

它还有一个作用,就是能够实现在构造器中调用构造器,从而减少代码的冗余。

1
2
3
4
5
6
7
8
Class A{
A(int i){
}
A(int i, int j){
this(i);
}
}

static的含义

用static关键字修饰的方法,表示它是静态方法,它没有this指针,在使用在时须注意一下几点:

  • static方法中不能调用非static方法和使用非static变量

  • 非static方法可以调用static方法

  • 在没有任何对象的前提下,可以使用类名调用static方法

清理:终结处理和垃圾回收

Java允许在类中定义一个名为finalize()的方法,一旦垃圾回收器准备释放对象所占用的内存空间,首先调用其finalize()方法,并在下一次垃圾回收动作发生时
真正的回收对象所占用的内存
。它不同于C++的析构函数,因为析构函数在释放内存时一定会被调用,而finalize()不会被调用,因此,把释放工作放在finalize()里是不可靠的,因为它不确保一定会被调用。那么,它的有什么作用呢?总结下来
有两个:

  1. 释放其他代码所申请的内存。比如C++代码申请的内存,垃圾回收器不能够释放。

  2. 释放内存前做一些验证操作,发现程序的缺陷。

finalize方法什么时候会被调用呢?

  1. 垃圾回收前
  2. 程序退出前,会调用所有对象的该方法
  3. 显式调用

初始化

成员初始化

对于方法的局部变量,Java会以编译时错误的形式来保证其初始化。而对于类的基本类型数据成员,如果没有初始化,那么编译器会自动帮其初始化(非基本类型的数据成员为null)。而关于初始化的顺序,则和成员定义的顺序相关。当然也可以指定初始化,即在类定义时直接赋值(C++不能这么做

1
2
3
4
public class A{
int a = 1;
double b = 2;
}

构造器初始化

在构造器中初始化成员变量,注意:它无法阻止自动初始化的进行,它将在构造被调用前自动初始化。例如:

1
2
3
4
5
6
public class A{
int i;
A(){
i = 1;
}
}

i先会赋值给0,在变成1。

静态对象会优先非静态对象进行初始化。并且静态对象只会初始化一次。

枚举类型

在java SE5后引入了枚举类型,它表示一组常量组成的集合,使用关键字enum定义。枚举类型是一个特殊的类(class),实际上它是继承了java.lang.Enum类。枚举类是final修饰的,所以它是不可继承的,它的枚举值都是静态常量,这也是我们为什么能够直接用类似Color.RED来直接访问。既然它的本质是class,那么它具有class的特性,例如:实现一个或多个接口;定义新的方法/变量。另外,相比于其他类,它还有些特点;

  • 构造函数时私有的,不能被外部调用,保证外部代码无法构建枚举类的实例。

  • 继承了枚举类的方法。例如:original() //返回int表示枚举值的顺序; values() //静态方法:返回所有枚举值构成的数组。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Class A{
    public enum Color{
    RED,BULE,GREEN
    public void otherMethod(){
    System.out.println("other");
    }
    }
    public static void main(){
    Color c = Color.RED;
    c.otherMethod();
    c.ordinal();
    Color [] colors = Color.values();
    }
    }