码迷,mamicode.com
首页 > 编程语言 > 详细

三、java的创建与销毁

时间:2015-07-26 00:23:17      阅读:123      评论:0      收藏:0      [点我收藏+]

标签:

宏观来看,任何语言都不能回避的两个问题:初始化和清理

一、初始化

1. java中初始化是和创建对象绑定在一起的

首先要明确一点,java中更普遍的类型是引用类型,虽然每本java的书籍里面都会先介绍八种基本数据类型,但是这八种实际上是特例。

一个值如果是属于某个类本身,那么它叫做成员变量;如果是在某个方法中定义的,那么它叫做局部变量。关于成员变量,java在新建对象的时候,会默认地给其成员变量自动初始化(这是出于安全性的考虑,避免程序员创建对象的时候忘记初始化)

自动初始化规则是:(后面介绍数组的时候,数组也会自动初始化,同样遵循下面的规则)
short,byte,int ,long :0
float,double :0.0
char: 空格
boolean :false
引用类型:null

事实上,自动初始化甚至发生在构造函数赋值之前,比如:

 1 public class Test {
 2     public static void main(String[] args) {
 3         A a = new A(1);
 4     }
 5 }
 6 
 7 class A {
 8     int i;
 9     public A() {}
10     public A(int i) {
11         this.i = i;
12     }
13 }

上面这段简单的代码, 在new A的时候,首先执行自动初始化i赋值为0,然后才执行的this.i=i,把i的值变为1.

2. 函数重载

上面的小例子中,A()和 A(int i)方法构成重载,这里就顺便提一点:区分重载的方式

参数的个数或者类型(顺序不同也可以作为重载的区分,但是不推荐)
-----注意两点:不能根据返回值来区分重载; 不能根据权限区分符public ,protected来区分;
这个地方这么来理解:因为你调用方法,肯定是要在方法执行之前就能够确定你要执行的是哪个方法, java也是这样的, “必须在执行前”这一点,就决定了不能够根据返回值来确定重载,因为能够得到返回值了,方法都执行完了;

3. 关于构造函数,主要提两点:

-----自定义一个类,最好是显式定义其无参构造方法;

-----this可以用于调用构造方法

普通方法里面不能通过this来调用构造方法,只有构造方法里面才可以;
一个构造方法里面只能运用一次this的方式来调用构造方法;
this调用构造方法,必须写在调用this的构造方法的第一句;

4.涉及到static的初始化:牢记一点,优先静态

 1 public class Test{
 2     static Bowl bowl = new Bowl(1);
 3     Test() {
 4         bowl.f1(1);
 5         bowl2.f1(2);//注意哦,bowl2的创建语句写在Test()之后
 6     }
 7     static Bowl bowl2  = new Bowl(2);
 8     
 9     public static void main(String[]args) {
10         Test t = new Test();
11     }
12 }
13 
14 class Bowl {
15     Bowl(int i) {
16         System.out.println("bowl:"+i);
17     }
18     void f1(int i) {
19         System.out.println("f1:"+i);
20     }
21 }

对象中的静态数据,会比构造方法还要先执行,因此上面调用Test()方法的时候bowl2已经执行完了,所以虽然bowl2的new语句写在后面,但是编译和运行都不会出问题。如果是非静态,这里编译就会报错。

关于static再看一个例子:

 1 public class Test{
 2     static int i=1;
 3     void nor() {
 4         System.out.println("普通方法执行:"+i);
 5     }
 6     static void  f() {
 7         i++;
 8         System.out.println("静态方法执行"+i);
 9     }
10     Test() {
11         i++;
12         System.out.println("构造方法执行:"+i);
13     }
14     public static void main(String[]args) {
15         System.out.println(Test.i);
16         Test.f();
17         new Test().nor();
18     }
19 }

结果如下:

 技术分享 

第一行结果为1,因为只执行 Test.i,在编译期间就能知道值,java不需要加载Test.class ,所以此时i还是1;
第二行调用f(),虽然它是静态的,但是还是需要加载Test.class ,所以i 变成 2;
第三行执行普通方法,要先建对象,更需要加载Test.class,i 变成 3;
并且,静态变量只会初始化一次

5.数组初始化

1)这里注意一下数组初始化的三中写法(面试常考)

int[] a = {1,2,3};
int[] a = new int[]{1,2,3};
int[] a = new int[3]; a[0]= 1,a[1]= 2,a[2]=3; //注意不要加 () ,就是 new int[3]

2)这里顺便提一下可变参数列表(貌似比较少看到有人用它),见下例:

 1 public class Test{
 2     public static void main(String[]args) {
 3         Object[] objs = {"String类型测试",1,1.1};
 4         new Test().printArray(objs);
 5         System.out.println("********");
 6         new Test().printArray2(objs);
 7         System.out.println("********");
 8         new Test().printArray2("我是String",2,2.2);
 9         System.out.println("********");
10         new Test().printArray2();
11     }
12     
13     public void printArray(Object[] objs) {
14         for(Object obj : objs) {
15             System.out.println(obj.toString());
16         }
17     }
18     
19     
20     public void printArray2(Object... objs ){
21         for(Object obj:objs) {
22             System.out.println(obj.toString());
23         }
24     }
25 }

 

结果如下:

技术分享

可以看到 ... 这个符号的含义,就是可变参数列表
上面printArray2中,如果传入普通参数,它会自动把获得的参数组装成为数组,然后自动放到objs中, 所以就可以直接用for-each循环打印了
而如果传入的本身就是数组形式,那么就不会再进行自动转换。
并且最后一行显示,表明,可变参数列表,即使什么都不传入也是可以的。

使用可变参数类型的时候,就需要注意一下重载的时候的一个小问题:

技术分享

之前介绍重载的时候讲到区分重载的方式是参数类型不同,这个例子可以认为是一个例外(也可以认为不是例外,因为可变参数列表底层最终也是转换成为数组来处理的)

 

二、清理

1)finalize() 

finalize()方法可以用来做一些清理前的工作,但是它不是类似于C++中的析构函数, 并不是写了就马上会被执行,这点一定要注意。
关于这一点的设计,也是java中一个比较智能的设计,因为去执行这些清理操作本身,就会要浪费你的内存,所以java设计的是没有必要写了finalize()马上就调用它(就像你被蚊子咬了一下,并不需要去住院一样)

关于finalize()方法不一定什么时候执行,必须要注意的是比如你写了数据库连接的语句,在执行完后要记得关闭流,这个关闭的操作要写在fanally中,而不是写在finalize()中。

2)finalize()的另一点

java中是可以调用C,C++的,但是java的清理机制并不能够自动销毁C,C++产生的内存消耗(比如java不能操作寄存器,但是C,C++却可以),那么常见的就是在finalize()里面写对应的C,C++的析构函数,来清理它们产生的垃圾。

 

三、java的创建与销毁

标签:

原文地址:http://www.cnblogs.com/kaiguoguo/p/4676822.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!