1.构造器
构造器是一种特殊类型的方法,因为它没有返回值;
在创建对象时,将会为对象分配存储空间,并调用相应的构造器。
2.方法重载
每个重载的方法都必须有一个独一无二的参数类型列表;
甚至参数顺序的不同也足以区分两个方法;不过,一般情况下不建议这么做,因为会使代码难以维护。
根据方法的返回值来区分重载方法是行不通的。
3.默认构造器
默认构造器又称“无参构造器”,它的作用是创建一个”默认对象“。如果你写的类中没有构造器,编译器会自动帮你创建一个默认构造器。
如果你提供了一个构造器(无论有参无参),则编译器会用你写的构造器。
4.this关键字
this关键字只能在方法内部使用,表示对“调用方法的那个对象”的引用。This的用法和其他对象引用并无不同。
如果一个类有多个构造器,有时可能想在一个构造器中调用另一个构造器,以避免重复代码。可以用关键字做到这一点。
示例:
importstatic net.mindview.util.Print.*;
publicclass Constructor { intpetalCount = 0; String s = "initialize value"; Constructor(int petals) { petalCount = petals; print("Constructor w/ int arg only, petalCount = " + petalCount); } Constructor (String ss) { print("Constructor w/ string arg only, s = " + ss); s = ss; } Constructor (String s, int petals) { this(petals); this.s = s; print("String & intg args"); } Constructor () { this ("hi", 47); print("default constructor (no args)"); } void printPetalCount() { print("petalCount = " + petalCount + " s = " + s); } publicstaticvoid main(String[] args) { Constructor cs = new Constructor(); cs.printPetalCount(); }
} |
结果:
Constructor w/ int arg only, petalCount = 47 String & intg args default constructor (no args) petalCount = 47 s = hi |
5.static的含义
static方法就是没有this的方法。在static方法的内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。这实际上正是static的主要用途。它很想全局方法。JAVA禁止使用全局方法,但你在类中置入static方法就可以访问其他static方法和static域。
6.finalize方法
存在这种特殊情况:假定你的对象(并非使用new)获得一块特殊的内存区域,由于垃圾回收器只知道释放那些经由new分配的内存,所以它不知道该如何释放该对象的这块“特殊”内存。为了应对这种情况,JAVA允许在类中定义一个名为finalize()的方法。它的工作原理是这样的:一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用其finalize()方法,并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存。所以你打算用finalize()方法,就能在垃圾回收时刻做一些重要的清理工作。之所以有finalize,是由于在分配内存时可能采用了类C语言中的做法,而非JAVA的通常做法。这种情况主要发生在使用“本地方法”的情况下。“本地方法”是一种在JAVA中调用非JAVA代码的方式。
JAVA里的对象并非总是被垃圾回收:
对象可能不被垃圾回收;
垃圾回收并不等于“析够“;
垃圾回收只与内存有关;
如果进行释放存储空间之外的清理工作,还是得明确调用某个恰当的JAVA方法。
Finalize示例
class Book { booleancheckedOut = false; Book(boolean checkOut) { checkedOut = checkOut; } void checkIn() { checkedOut = false; } protectedvoid finalize() { if (checkedOut) { System.out.println("Error: checked out"); // Normally, you will also do this: // super.finalize(); //call the base-class version } } } publicclass TermCondition { publicstaticvoid main(String[] args) { Book novel = new Book(true); novel.checkIn(); new Book(true); //Force garbage collection & finalization System.gc(); }
} |
结果:
Error: checked out |
System.gc()用于强制进行终结动作;
7.成员初始化
JAVA尽力保证:所以变量在使用前都能恰当的初始化:
指定初始化(在定义类成员变量的地方为其赋值)
构造器初始化(构造器被调用之前,会执行自动初始化和指定初始化)
在类的内部,变量定义的先后顺序决定了初始化的顺序。
类初始化的顺序是:先静态域,后非静态域;静态域只初始化一次。
8.数组初始化
编译器不允许指定数组的大小;
所有数组,都有一个固有成员length,通过他可以知道数组包含了多少个元素;JAVA数组计数从0个元素开始,所以能使用的最大的下标数是length-1。
如果你创建了一个非基本类型的数组,那么你就创建了一个引用数组。
示例
import java.util.*; importstatic net.mindview.util.Print.*;
publicclass ArrayClass { publicstaticvoid main(String[] args) { Random rand = new Random(47); Integer[] a = new Integer[rand.nextInt(20)]; //print("length of a = " + a.length); for (int i = 0; i < a.length; i++) a[i] = rand.nextInt(500); Integer[] b = a; print("lengtgh of b = " + b.length); print(Arrays.toString(b)); }
} |
结果
lengtgh of b = 18 [55, 193, 361, 461, 429, 368, 200, 22, 207, 288, 128, 51, 89, 309, 278, 498, 361, 20] |
数组也可以用花括号括起来的列表来初始化。
示例
import java.util.*;
publicclass ArrayInit { publicstaticvoid main(String[] args) { Integer[] a = { new Integer(1), new Integer(2), 3, }; Integer[] b = new Integer[] { new Integer(1), new Integer(2), 3, }; System.out.println(Arrays.toString(a)); System.out.println(Arrays.toString(b)); }
} |
结果
[1, 2, 3] [1, 2, 3] |
9.可变参数列表
示例
publicclass NewVarArgs { staticvoid printArray(Object ... args) { for (Object obj : args) System.out.print(obj + " "); System.out.println(); } publicstaticvoid main(String[] args) { printArray(new Integer(47), new Float(3.14), new Double(11.11)); printArray(47, 3.14F, 11.11); printArray("one", "two", "three"); printArray(new A(), new A(), new A()); printArray(); }
} |
结果
47 3.14 11.11 47 3.14 11.11 one two three A@87816d A@422ede A@112f614 |
10.枚举类型
尽管enum看起来像是一种新的数据类型,但是这个关键字只是为enum生成对应的类时,产生了某种编译器行为,因此很大程度上,你可以将enum当作其他任何类来处理。事实上,enum确实是类,并且具有自己的方法。
示例
publicclass EnumOrder { publicenum Spiciness { NOT, MILD, MEDIUM, HOT, FLAMING } publicstaticvoid main(String[] args) { for (Spiciness s: Spiciness.values()) System.out.println(s + ", ordinal " + s.ordinal()); }
} |
结果
NOT, ordinal 0 MILD, ordinal 1 MEDIUM, ordinal 2 HOT, ordinal 3 FLAMING, ordinal 4 |
由于switch是要在有限的可能值集合中进行选择,因此它与enum是绝佳的组合。