Thinking in Java第五章学习笔记----初始化与清理

初始化与清理

  初始化和清理是涉及程序安全的两个问题。Java构造器用于新建对象时的初始化,而垃圾回收器则进行清理。

构造器

  其名称必须与类名一样,虽然构造器是一种特殊的方法,但是每个方法首字母小写的编码风格并不适合用于构造器。

  构造器是没有返回值的,但是new表达式却返回了对新建对象的引用。

方法重载

  方法重载是构造器所必须的。每个重载方法都必须独一无二的参数列表。甚至参数顺序的不同,也足以区分两个方法。不过一般不建议这么做,因为这会使代码难以维护。当传入的数据类型小于方法中声明的形式参数类型,实际数据类型就会被提升。但是boolean不能转换,char也比较特殊,提升至int。如果反过来,传入大于声明,则必须进行强转,否则报错。(注意,根据返回值的不同来区分方法是不成立的。)

各参数类型大小顺序排列

  boolean:1/8;byte:1;char:2(一个字符可以存储一个中文汉字);short:2;int:4;float:4;long:8;double:8。(单位:字节)

this关键字

  只能在方法内部使用,表示对"调用方法的那个对象"的引用。只有在需要明确指出对当前对象的引用时,才有必要使用this。如果在方法内部使用同一个类中的另一个方法,就不用使用this。return this表示返回当前引用。

  通常写this的时候,都是指"这个对象"或者"那个对象",而且它本身表示对当前对象的引用。在构造器中,如果this添加了参数列表,那么就有了不同的含义。这将产生对符合此参数列表的某个构造器的明确调用。通过下面的代码示例将会理解的更加深刻。

public class Flower {
	int petalCount = 0;
	String s = "initial value";
	Flower(int petals){
		petalCount = petals;
		System.out.println("Constructor w/ int arg only,petalCount=" + petalCount);
	}
	Flower(String ss){
		System.out.println("Constructor w/ String arg only,s=" + ss);
		s = ss;
	}
	Flower(String s,int petals){
		this(petals);
         //this(s)//错误,不能在一个构造器里面调用两次构造器 this.s = s;//因为成员名字和参数S的名称一致,所有采用这种写法加以区分。 System.out.println("String & int args"); } Flower(){ this("hi",47); System.out.println("default constructor(no args)"); } void printPetalCount(){
         //this(11);//错误,不能在非构造器方法里通过this调用构造器。 System.out.println("petalCount =" + petalCount + " s=" + s); } public static void main(String[] args){ Flower x = new Flower(); x.printPetalCount(); } }

output:

Constructor w/ int arg only,petalCount=47
String & int args
default constructor(no args)
petalCount =47 s=hi

 关于static的补充

  static方法不能包含this,即不能调用非静态方法。反过来倒是可以。而且在没有创建对象的时候,单依靠对象本身就可以对static方法进行调用。这实际上是static的主要作用。这很像全局方法,Java中禁止使用全局方法,但你在类中置入static方法,就可以访问其他的static方法和static域。

  有些人认为static方法不是"面向对象"的,因为他们的确具有全局函数的含义,使用static方法时,由于并不是通过this来向对象发送信息。的确,要是代码中存在大量的static,就应该重新考虑自己的设计。然而static的概念有其实用之处,许多时候都要用到它,至于是不是面向对象,不是我们说了算的。

******************************关于终结处理和垃圾回收,将在后面的博文中详细介绍。******************************

初始化

  Java尽力保证:所有变量在使用前必须得到恰当的初始化。

  对于类中基本成员(即字段)是基本类型的,会自动为这些成员初始化。但是方法中的局部变量则不会,必须强制程序员赋予初始值,否则编译报错。

成员初始化的三种情况

  (1)类中基本成员变量:直接在定义的地方为其赋值。(C++中不可以)

  (2)非基本类型的对象:

class Depth{}

public class Measurement {
	Depth d = new Depth();
}

   (3)通过调用某个方法来提供初值,这个方法也可以带有参数,但是这些参数必须是已被初始化了的:

public calss MethodInit2{
	int i = f();
	int j = g(i);
	int f(){
		return 11;
	}
	int g(int n){
		return n * 10;
	}
}

构造器初始化

  (1)初始化顺序(牢记):在类的内部,变量定义的顺序决定了初始化的顺序,即使变量定义或者创建对象引用散布于各方法之间,它们仍旧会在任何方法(包括构造器)被调用之前得到初始化。

  (2)静态数据的初始化:static关键字不能作用于局部变量,只能作用于域,即成员变量或者对象引用。如果一个域是静态的基本类型域,且没有对它进行初始化,那么它将获得基本类型的标准值,如果它是一个对象引用,那么初始值为null。初始化的查询是先静态对象,再非静态对象。

class Bowl {
    Bowl(int marker) {
        System.out.println("Bowl(" + marker + " )");
    }
    void f1(int marker) {
        System.out.println("f1(" + marker + ")");
    }
}
class Table {
    static Bowl bow1 = new Bowl(1);
    Table() {
        System.out.println("table()");
        bowl2.f1(1);
    }
    void f2(int marker) {
        System.out.println("f2(" + marker + ")");
    }
    static Bowl bowl2 = new Bowl(2);
}
class Cupboard {
    Bowl bowl3 = new Bowl(3);//此处的初始化会在静态对象之后。
    static Bowl bowl4 = new Bowl(4);
    Cupboard() {
        System.out.println("cupboard()");
        bowl4.f1(2);
    }
    void f3(int marker) {
        System.out.println("f3(" + marker + ")");
    }
    static Bowl bowl5 = new Bowl(5);
}
public class StaticTest {
    public static void main(String[] args) {
        System.out.println("creating new cupboard in main");
        new Cupboard();
        System.out.println("creating new cupboard() in main");
        new Cupboard();//此处虽然创建了Cupboard对象,但是静态bowl4和bowl5不会再次被初始化。
        table.f2(1);//这里如果对象引用不是static型,直接使用table.f2是会报错的。下行类似。
        cupboard.f3(1);
    }
    static Table table = new Table();//只有创建Table对象,而且引用静态域时,静态的bowl1和bowl2才会创建。下行类似。
    static Cupboard cupboard = new Cupboard();//第一次对bowl4和bowl5进行初始化。
}

output:

Bowl(1 )
Bowl(2 )
table()
f1(1)
Bowl(4 )
Bowl(5 )
Bowl(3 )
cupboard()
f1(2)
creating new cupboard in main
Bowl(3 )
cupboard()
f1(2)
creating new cupboard() in main
Bowl(3 )
cupboard()
f1(2)
f2(1)
f3(1)

 显式的静态初始化

  Java允许将对个静态子句组织成一个特殊的静态块。

class Spoon{
    static int i;
    static int j;
    static Spoon spoon1;
    static{
        i = 7;
        j = 5;
        spoon1 = new Spoon();
    }
}

非静态实例初始化:

  和上面类似,可以集中进行初始化。只不过少了static关键字。

数组初始化:

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

  改变a2中的值,将会影响a1,因为是将a1的引用赋值给了数组a2,a1和a2是不同名的同一数组。 

转载于:https://www.cnblogs.com/promiseslc/p/8626403.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值