Java编程思想读书笔记--第五章笔记(初始化与清理)
程序员文章站
2024-03-17 18:23:46
...
Java编程思想读书笔记–第五章笔记(初始化与清理)
- 构造器
- 方法重载
- 默认构造器
- this关键字
- 在构造器中调用构造器
- static关键字
- 终结处理和垃圾回收
- 成员初始化
- 构造器初始化
- 数组初始化
- 可变参数
- 枚举类型
构造器
方法重载
public class Code_11_PrimitiveOverLoad {
public static void f1(int x){
System.out.println("int " + x);
}
public static void f1(long x){
System.out.println("long " + x);
}
public static void main(String[] args) {
f1(5);
}
}
输出:
int 5
上面的输出毫无疑问:
但是要注意如果注释掉 f1(int x)那个方法
/**
* 重载方法的方法选择
*/
public class Code_11_PrimitiveOverLoad {
public static void f1(long x){
System.out.println("long " + x);
}
public static void main(String[] args) {
f1(5);
}
}
输出
long 5
说明实际参数大于形式参数也可以转型:
public class Code_11_PrimitiveOverLoad {
public static void f2(long c){
System.out.println("long " + c); //99
}
public static void f2(int c){
System.out.println("int " + c);//输出99
}
public static void f2(char c){
System.out.println("char " + c);//c
}
public static void main(String[] args) {
f2('a');
}
}
上面的三个方法都可以传入,顺序是char > int > long ;
但是如果传入的参数大于形式参数就会编译器报错(必须通过类型转换来执行窄化转换):
还有,不能使用返回值来区分重载的方法:
默认构造器
this关键字
public class Code_02_ThisTest {
private static class Leaf {
int i = 0;
Leaf increment() {
i++;
return this; //这里返回的是 当前对象的引用
}
void print() {
System.out.println("i = " + i);
}
}
public static void main(String[] args) {
Leaf x = new Leaf();
x.increment().increment().increment().print();
}
}
输出 :
i = 3
/**
* 测试this关键字
*/
public class Code_03_ThisTest2 {
private static class Person {
public void eat(Apple apple) {
Apple peeled = apple.getPeeled(); //返回的就是main中构造的
System.out.println(peeled); //输出对象的引用
System.out.println("Yummy");
}
}
private static class Peeler {
public static Apple peel(Apple apple) {
return apple;
}
}
private static class Apple {
Apple getPeeled() {
return Peeler.peel(this); //这里传入的是构造的当前的对象
}
}
public static void main(String[] args) {
// new Person().eat(new Apple());
Apple apple = new Apple();
System.out.println(apple);
new Person().eat(apple);
}
}
chapter5.Code_03_ThisTest2$Apple@135fbaa4
chapter5.Code_03_ThisTest2$Apple@135fbaa4
Yummy
可以看到两个引用是一样的;
在构造器中调用构造器
public class Code_04_ThisTest3 {
public static class Flower {
int petalCount = 0;
String s = "initial value";
Flower(int petals) {
petalCount = petals;
System.out.println("int类型参数 ,petalCount= " + petalCount);
}
Flower(String ss) {
System.out.println("String类型参数 , s = " + ss);
s = ss;
}
Flower(String s, int petals) {
this(petals); //必须在开头就调用构造器
//this(s); // 不能调用两个构造器
this.s = s; // Another use of "this"
System.out.println("String 和 int 参数");
}
Flower() {
this("hi", 47);
System.out.println("默认构造器,无参数");
}
void printPetalCount() { //不能在除构造器之外的任何方法调用构造器
//this(11);
System.out.println("petalCount = " + petalCount + " s = "+ s);
}
public static void main(String[] args) {
Flower x = new Flower();
System.out.println("-----------");
x.printPetalCount();
}
}
}
输出:
int类型参数 ,petalCount= 47
String 和 int 参数
默认构造器,无参数
-----------
petalCount = 47 s = hi
static关键字
终结处理和垃圾回收
public class TerminnationCondition {
public static void main(String[] args) {
Book novel = new Book(true);
novel.checkIn();// Proper cleanup:
new Book(true);// Drop the reference, forget to clean up: (忘记了)
System.gc();// Force garbage collection & finalization:
}
}
class Book {
boolean checkedOut = false;
Book(boolean checkOut) {
checkedOut = checkOut;
}
void checkIn() {
checkedOut = false;
}
protected void finalize() throws Throwable {
if(checkedOut)
System.out.println("Error: checked out");
super.finalize(); // Normally, you'll also do this:
}
}
输出:
Error: checked out
成员初始化
Java尽力保证: 所有变量在使用前都能得到正确的初始化。
- 对于方法的局部变量,Java以编译时错误的形式来贯彻这种保证;
- 如果是类的数据成员,且是基本类型,则每个数据成员都会有一个初始值,char为0(显示空白);
- 在类中定义一个对象引用时,如果不将其初始化,此引用将会获得一个特殊值null;
构造器初始化
初始化顺序
class Window {
Window(int marker) {
System.out.println("Window(" + marker + ")");
}
}
class House {
Window w1 = new Window(1); // Before constructor
House() {
System.out.println("House()");
w3 = new Window(33); // Reinitialize w3
}
Window w2 = new Window(2); // After constructor
void f() {
System.out.println("f()");
}
Window w3 = new Window(3); // At end
}
public class Code_01_OrderOfInitialization {
public static void main(String[] args) {
House h = new House();
h.f(); // Shows that construction is done
}
}
输出:
Window(1)
Window(2)
Window(3)
House()
Window(33)
f()
静态数据初始化
/**
* 静态数据初始化
*/
class Bowl {
Bowl(int marker) {
System.out.println("Bowl(" + marker + ")");
}
void f1(int marker) {
System.out.println("f1(" + marker + ")");
}
}
class Table {
static Bowl bowl1 = 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 StaticInitialization {
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();
System.out.println("------------------");
table.f2(1);
cupboard.f3(1);
}
static Table table = new Table();
static Cupboard cupboard = new Cupboard();
}
输出:
静态代码块
静态代码块仅执行一次,发生在:
- 首次生成这个类的一个对象时;
- 或者首次访问属于那个类的静态数据成员时(即便从未生成过那个类的对象);
/**
* 静态代码块比构造函数先执行
*/
class Cup {
Cup(int marker) {
System.out.println("Cup(" + marker + ")");
}
void f(int marker) {
System.out.println("f(" + marker + ")");
}
}
class Cups {
static Cup cup1;
static Cup cup2;
static {
cup1 = new Cup(1);
cup2 = new Cup(2);
}
Cups() {
System.out.println("Cups()");
}
}
public class ExplicitStatic {
public static void main(String[] args) {
System.out.println("Inside main()");
Cups.cup1.f(99); // (1)
}
// static Cups cups1 = new Cups(); // (2)
// static Cups cups2 = new Cups(); // (2)
}
实例初始化
class Mug {
Mug(int marker) {
System.out.println("Mug(" + marker + ")");
}
void f(int marker) {
System.out.println("f(" + marker + ")");
}
}
public class Mugs {
Mug mug1;
Mug mug2;
{
mug1 = new Mug(1);
mug2 = new Mug(2);
System.out.println("mug1 & mug2 initialized");
}
Mugs() {
System.out.println("Mugs()");
}
Mugs(int i) {
System.out.println("Mugs(int)");
}
public static void main(String[] args) {
System.out.println("Inside main()");
new Mugs();
System.out.println("new Mugs() completed");
System.out.println("---------------------");
new Mugs(1);
System.out.println("new Mugs(1) completed");
}
}
输出:
数组初始化
import java.util.Arrays;
public class Code_07_ArrayInit {
public static void main(String[] args) {
Integer[] a = {
new Integer(1),
new Integer(2),
3, // Autoboxing 自动 装箱
};
Integer[] b = new Integer[]{
new Integer(1),
new Integer(2),
3, // Autoboxing
};
System.out.println(Arrays.toString(a));
System.out.println(Arrays.toString(b));
}
}
public class Code_08_DymanicArray {
public static void main(String[] args) {
Other.main(new String[]{ "fiddle", "de", "dum" });
}
}
class Other {
public static void main(String[] args) {
for(String s : args)
System.out.print(s + " ");
}
}
输出:
fiddle de dum
可变参数
class A{}
public class Code_09_NewVarArgs {
static void printArray(Object... args) {
for(Object obj : args)
System.out.print(obj + " ");
System.out.println();
}
public static void 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((Object[])new Integer[]{ 1, 2, 3, 4 });
printArray(); // Empty list is OK
}
}
输出:
枚举类型
另外,枚举类型和switch放在一起使用是绝佳配合。放在case ;中。
上一篇: Java编程思想笔记——持有对象
下一篇: 之前写的jq的公共方法,一些常用内容合集