初始化和清除
构造函数负责初始化,分配空间。
构建器,无返回值,可过载overloading
方法过载overloading(根据参数不同而区分)不能根据返回值
相同名字的方法。
主类型的过载: 若我们的数据类型小于方法中的自变量,就会向上cast,转换。 如果是大于的话,需要强制转换(信息可能丢失)
默认构造器:创建一个空对象。如果定义一个构建器,那么就不会使用默认的构建器。
“this”关键字,表示调用它的对象的句柄。//当前对象的句柄
在构建器中调用构建器。使用“this”关键字。例如:
public class Moop{
int lit;
int pak;
public Moop(int x){
lit = x;
}
public Moop(int x,int y){
this(x); //在构建器中调用了构建器。this表示当前对象句柄。
pak = y;
}
}
“static”关键字,static定义的方法没有this句柄
注意:我们不可以从一个static方法内部发出对非static方法的调用,除非将以个句柄传到static方法内部。
清除:收尾和垃圾收集
垃圾收集器只知道释放new分配的内存。当需要释放一些特殊内存的时候,Java提供了一个名为finalize ()的方法。可以在我们的类中定义它。
finalize()工作原理:当垃圾收集器准备好释放对象空间,它首先调用finalize()方法,并且需要在下一次垃圾收集的过程中才真正回收对象内存。
三个重点:
1、垃圾收集并不等于“破坏”(释放)Java对象并非肯定最为对象被收集。
2、我们的对象可能不会当作垃圾被收集掉。
3、垃圾收集只和内存有关。
什么时候用finalize()呢?答案是最好不用。似乎finalize()没有多少用途,只是在一些特殊的地方。非Java对象调用。
C++ 中的所有对象都必须“破坏”,而Java中大多时候由垃圾收集器来完成。finalize()最有用的地方就是观察垃圾收集过程。
例:
//:Garbage.java
//Demonstrate of the garbage
//Collector and finalization
class Chair{
static boolean gcrun = false;
static boolean f = false;
static int created = 0;
static int finalized = 0;
int i;
Chair(){
i = ++created ;
if(created == 47)
System.out.println("Created 47");
}
protected void finalize(){
if(!gcrun){
gcrun = false;
System.out.println(Beginning to finalize after "+created+" Chairs have been created");
}
if(i == 47){
System.out.println(‘Finalizeing Chair #47,"+"Setting flag to stop Chair creation");
f = true;
}
finalized++;
if(finalized >= crated)
System.out.println("All" + finalized + "finalized");
}
}
public class Garbage{
public static void main(String[] args){
if(args.length == 0){
System.out.println("Usage:\n"+
"Java Garbage before\n or:\n"+
"Java Garbage after");
return;
}
while(!Chair.f){
new Chair();
new String("TO take up space");
}
System.out.println("After all Chairs have been created:\n"+ "total created = "+Chair.created+
", toatl finalized = " +Chair.finalized);
if(args[0].equals("before")){
System.out.println("gc():");
System.gc();
System.out.,println("runFinalization():");
System.runFinalization();
System.out.println("bye");
}
if(args[0].equals("after")){
System.runFinalizerOnExit(true);
}
}
System.runFinalization()( 收尾)与垃圾收集是否运行无关。Sun公司文档称应该先运行收尾模块,然后再释放存储空间,然而这里若先调用System.runFinalization(),再调用 System.gc(),则收尾模块根本不会运行。(可以自己试一下,我还没有试)
成员初始化:
若程序员没有初始化,那编译器会为他们赋一个值:
Data Type Inital value
boolean false
char (Null,不显示)
byte 0
short 0
int 0
long 0
float 0.0
double 0.0
规定初始化:在定义同时赋初值(C++ 中不能这样做)可以用new,方法(带返回值)来初始化
构建器初始化:在用此初始化之前定义的数据成员已经被编译器赋给默认值,所以在构建器中没有强迫我们初始化。
静态数据的初始化:static的初始化只有在必要的时候才会进行。初始化时首先是static
对象的创建过程:以名为Dog的类为例
1.类型为Dog的一个对象首次创建时,或Dog类的static方法/static字段首次访问时,Java解释器必须找到Dog.class(在环境变量中设置搜索路径)
2.找到Dog.class后(它会创建一个class对象) 它的所有static初始化模块都会运行.因此,static初始化仅发生一次,即在class对象首次装载时。
3.创建一个new Dog()时,Dog对象分配足够的内存存储空间。
4.这种存储空间会清为零,将Dog中所有基本类型设为他们的默认值。
5.进行字段定义时发生的初始化都会执行。
6.执行构建器。
明确进行静态初始化
例:
class Spoon{
static int i;
static{ //静态初始化开始
i = 47;
}
}
数组初始化: Java中的数组大小在编译的时候才决定,在运行的时候才创建。在编译的时候进行边界检查。牺牲性能换来安全。
int[] a1 = {1,2,3,4,5};
int[] a2 ;
a2 = a1; //复制一个句柄。
对于非基本数据类型的数组初始化:使用new
Integer[] a = new Integer[] { //java1.1以后版本支持
new Integer(1);
new Integer(2);
};
Integer[] a = { //java 1.0 版本支持(唯一)
new Integer(1);
new Integer(2);
}
未知参数数量大小,及类型:变参表
//:VarArgs.java
//Using the Java1.1 array syntax to create
//varivale argument lists
class A{int i;}
public class VarArgs{
static void f(Object[] x){
for(int i = 0 ; i < x.length ; i++)
System.out.println(x[i]); //每一个Object都有一个toString(),自动转换
}
public static void main(String[] args){
f(new Object[]{ //不同的类型
new Integer(47),new VarArgs(),
new Float(3.14),new Double(11.11)});
f(new Object[]{"one","two","three"});
f(new Object[]{new A(),new A(),new A()});
}
}
多维数组初始化:
int[][] a1 = {
{1,2,3},
{4,5,6},
};
Integer[][] a2 = {
{new Integer(1),new Integer(2)},
{new Integer(3),new Integer(4)},
{new Integer(5),new Integer(6)},
}
int[][][[] a3 = new int[pRand(7)][][]; //pRand(int)是一个随机方法
for(int i = 0; i < a3.length;i++){
a3[i] = new int[pRand{5)][];
for(int j = 0 ;j<a3[i].length;j++)
a3[i][j] = new int[pRand(5)];
}