thinkinginjava学习笔记04_初始化与清理

java沿用了c++的构造器,使用一个和类名完全一样的方法作为类的构造器,可以有多个构造器来通过不同的参数进行构造,称为重载;不仅是构造器可以重载,其他方法也一样通过不同的形参以及不同的返回值来实现重载;

当创建一个新的对象的时候,java就需要对该对象进行初始化(如果没有创建构造器,java会自动创建一个无参构造器,也称默认构造器,并对对象进行初始化),构造器函数只对对象进行初始化操作,并没有任何返回值(也不是返回void);

java中区分两个方法时,使用每个方法的参数列表(包括参数的顺序),参数列表的不同就会形成重载,方法的返回值不同同样会形成重载;

当重载涉及到基本类型的时候,如果传入的参数大小较小,则将自动转成形参中较大的类型;优先使用相同基本类型形参的方法进行调用,如果找不到,则会使用比较大的形参方法进行调用,并且自动将传入参数做相应的放大类型转换;如果只能找到较小的形参方法时,必须进行参数类型转换(窄化转换),否则编译器将报错;

如果类中没有构造器,则java会自动创建一个默认构造器,如果定义了构造器,则java不再创建默认构造器;

概念比较多,举个重载方法的例子:

class Human{

 

}

 

class Host extends Human{

 

}

 

class Stranger extends Human{

 

}

 

class Dog{

    void bark(Host h){

        System.out.println("She is wagging...");

    }

    void bark(Dog d){

        System.out.println("She is harking!");

    }

    void bark(Stranger s){

        System.out.println("She is howling!");

    }

}

 

public class TestInit {

    public static void main(String[] argv){

        Dog dog1 = new Dog();

        Dog dog2 = new Dog();

        Host h = new Host();

        Stranger s = new Stranger();

        dog1.bark(dog2);

        dog1.bark(h);

        dog1.bark(s);

    }

}/* output:

She is harking!

She is wagging...

She is howling!

*/

this关键字:如学习的感受,java中方法不需要显示的self(或者this)形参,this会再方法调用的时候自动传入,因此,java的类中,如果没有做其他处理(比如加static等),都是对象方法;并且在java的类中,调用当前对象的其他方法不需要显示指定this.method(),(并且最好不要添加)编译器会自动完成该工作,this的作用更多是在对象传递的时候使用,比如返回当前对象以及将当前对象传递给其他的方法;也可以通过this在构造器中调用比较简单的构造器来实现代码复用;

this的使用总结起来就是,在只能通过this进行明确表示传入该对象时才使用,否则都不要使用this;

通过static指定静态方法,静态方法不会传入this;关于书上说静态方法不“面向对象”,我认为Ruby已经给出了答案,类本身也是对象,可以将静态对象看做是类的一个单件方法,该单件方法可以被类调用,同样也在该类实例化对象的祖先链中存在;唯一的不同可能就是不会传入this了;

java中支持一个名为finalize()的方法,该方法可以在对象被回收前自动调用,相当于PHP中的__destructor(),同样的,该方法并不是析构方法,但是却可以通过该方法来检查对象被回收时的状态;

java中的垃圾回收并非通过引用计数的方式(之前的猜测有误),java具有多种回收机制,但是不包括引用计数的方式;具体方式有些复杂,以后有兴趣再深究;

java中的局部变量必须初始化,否则将会以报错的形式通知开发者,而类中的数据成员则会自动进行初始化;

数据成员初始化可以直接指定,也可以通过方法返回值,或者构造器来进行初始化;当两者同时进行时,变量会在方法(包括构造器)调用之前得到初始化;

初始化顺序:

静态数据成员->数据成员->构造器;但是,静态方法只在必要的时候才会被初始化;

通过一个花括号,可以对数据成员进行显示的初始化,如:

static int i;
static{
    i = 47;
}

int j;
{
    j = 34;

数组初始化:

java中通过一个方括号定义基本类型数组,如:

int[] a1;

int a1[];

上面两种形式具有相同的含义,数组通过一个花括号的列表进行初始化 ,如:

int a1[] = {1,2,3,4,5};

基本类型数组存在于栈中,和基本类型一样,引用数组通过一个包装器类型来定义:

Integer a2[] = new Integer[5];

引用数组并非对象本身是一个引用,而是数组中的元素都是引用(对象),引用数组的定义类似:

Integer a2[] = {
    new Integer(1),
    new Integer(2),
    3,
};

在引用数组中,如果有基本数据类型,则会自动调用包装器类型进行包装,如上例的3;

不论是基本类型数组还是引用数组,都有一个成员:length,显示该数组的长度,当数组下标越界时,java会报错;

通过设置一个数组参数,可以实现方法的可变参数列表,而在Jave SE5之后,可变参数列表作为特性使用,具体方式为:

void aMethod(Object… args){

}

先指定可变参数列表的类型,然后紧跟三个点,接着是参数名称;

有了该特性的支持,就不需要再显式编写数组语法来传递参数,然而当指定了可变参数列表时,java会自动地填充数组,并且如果传入的是一个数组,java变不会继续填充,而是直接使用该数组;(这样的操作不知道是多余还是简洁。。。)

由于以上不太能理解的方式,所以可变列表的引用使得重载的过程变得复杂,必要时需要通过添加非可变参数来解决问题;(有点怀念python简洁的语法了,尽管是数组,仍然会当成一个单一对象传入,这样更加容易理解并且避免很多问题,虽然python没有java的重载)

这章概括性有点强,似乎力求将所有的初始化都提及了,所以应该以后还会返回来再看的吧。

原文地址:https://www.cnblogs.com/lyon2014/p/4762119.html