Java编程思想—第5章 初始化与清理

5.1 用构造器确保初始化

  1. 创建对象时,如果其具有构造器,Java就会在用户有能力操作对象之前自动调用相应的构造器,从而保证了初始化的进行。
  2. 构造函数名与类名相同,无返回值,无参数的为无参构造器,可以传参,可以重载
  3. 在Java中,”初始化“和”创建“捆绑在一起,两者不能分离

5.2 方法重载

  1. 区分重载方法
    a. 每个重载的方法都必须有一个独一无二的参数类型列表。甚至参数顺序的不同也足以区分两个方法。不过,一般别这么做,因为这会使代码难以维护。
  2. 涉及基本类型的重载
    a. 如果传入的数据类型(实际参数类型)小于方法中声明的形式参数类型,实际数据类型就会被提升。char型略有不同,如果无法找到恰好接受char参数的方法,就会把char直接提升至int型。
    b. 如果传入的实际参数较大,就得通过类型转换来执行窄化转换。如果不这样做,编译器就会报错。
  3. 根据方法的返回值来区分重载方法是行不通的。

5.3 默认构造器

  1. 如果已经定义了一个构造器(无论是否有参数),编译器都不会帮你自动创建默认构造器

5.4 this关键字

a.pell(1);
//编译器的工作,我们自己不能这么写
Banana.pell(a,1);
  1. this关键字只能在方法内部使用,表示对“调用方法的那个对象”的引用
  2. this关键字对于将当前对象传递给其他方法也很有用
  3. 在构造器里调用构造器
    a. 尽管可以用this调用一个构造器,但却不能调用两个。此外,必须将构造器调用置于最起始处,否则编译器会报错。
    b. 除构造器之外,编译器禁止在其他任何方法中调用构造器。
Flower(){
    this("hi",47);
    print("在构造器中调用构造器");
}
  1. static的含义
    a. static方法就是没有this的方法
    b. 在static方法的内部不能调用非静态方法,反过来倒是可以。
    c. 可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法

5.5 清理:终结处理和垃圾回收

  1. 垃圾回收器只知道释放哪些经由new分配的内存
  2. 对象可能不被垃圾回收
  3. 垃圾回收并不等于析构
  4. finalize()的用途何在
    a. 垃圾回收只与内存有关
    b. 无论对象时如何创建的,垃圾回收器都会负责释放对象占据的所有内存。一种例外情况,通过某种创建对象方式以外的方式为对选哪个分配了存储空间。
    c. 主要应用在调用本地方法(C/C++中的代码)时,需要使用free()之类的函数释放内存
  5. 无论是“垃圾回收”还是“终结”,都不保证一定会发生。如果Java虚拟机(JVM)并未面临内存耗尽的情形,他还是不会浪费时间去执行垃圾回收以恢复内存的。
  6. 终结条件,用finalize()可以检测出不满足条件的对象
  7. 垃圾回收器对于提高对象的创建速度,具有明显的效果
  8. 垃圾回收器工作时,一面回收空间,一面使堆中的对象紧凑排列,这样“堆指针”就可以很容易移动到更靠近传送带的开始处,也就尽量避免了页面错误。通过垃圾回收器对对象重新排列,实现了一种高速的、有无限空间可分配的堆模型。
    a. 引用计数是一种简单但速度很慢的垃圾回收技术。
    b. JVM的一些知识

5.6 成员初始化

  1. Java尽力保证:所有变量在使用前都能得到恰当的初始化。对于方法的局部变量,Java以编译时错误的形式来贯穿这种保证。
  2. 类的每个基本类型数据成员保证都会有一个初始值
  3. 指定初始化:Java在类中指定字段初始值,但在C++中不行

5.7 构造器初始化

  1. 无法阻止自动初始化的进行,它将在构造器被调用之前发生。
  2. 初始化顺序:在类的内部,变量定义的先后顺序决定了初始化的顺序,但都是在方法定义之前定义
  3. 静态数据的初始化:静态初始化只有在必要时刻才会进行,当创建的第一个对象对静态数据初始化了,后面的对象就不会对其进行初始化。
  4. 即使没有显示地使用static关键字,构造器实际上也是静态方法。(构造器可以看成静态方法)
  5. 显示的静态初始化
    a. Java允许将多个静态初始化动作组织成一个特殊的“静态子句”(有时也叫做“静态块”)
public class Spoon{
    static int i;
    static {
        i = 47;
    }
}

  这段代码只执行一次:当首次生成这个类的一个对象时,或者首次访问属于那个类的静态数据成员时(即便从没发生过那个类的对象)。
 6. 非静态实例初始化:这种语法对于支持“匿名内部类”的初始化是必须的,但是它也使得你可以保证无论调用了哪个显示构造器,某些操作都会发生。

5.8 数组初始化

  1. 数组定义,Java中可以将一个数组赋值给另一个数组
int[] a1;  //常用
int a[]; 
  1. 编译器不允许指定数组的大小。数组初始化
int[] a1 = {1, 2, 3, 4, 5};
a1 = new int[5];
  1. 可变参数列表
    a. 一般使用Object类型作为祖先类型
    b. 当int类型和Integer类型同时存在时,会将int提升为Integer
public class Main {

    static void printArray(Object... args){
        for(Object obj : args){
            System.out.println(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((Object[])new Integer[]{1, 2, 3, 4});  //传入Object类型,可以通用
        printArray();
    }
}

//结果
47 
3.14 
11.11 

47 
3.14 
11.11 

one 
two 
three 

1 
2 
3 
4 

5.9 枚举类型

  1. enum关键字来定义枚举类型
public enum Spiciness{
    NOT, MILD, MEDIUM, HOT, FLAMING
}
  1. 枚举量为常量,应该使用大写
  2. 大体上,你可以将enum用作另外一种创建数据类型的方式,然后直接将所得到的类型拿来使用

5.10 总结

  1. 初始化在Java中占有至关重要的地位
  2. 由于要保证所有对象都被创建,构造器实际上要比这里所讨论的更加复杂
发布了77 篇原创文章 · 获赞 20 · 访问量 5775

猜你喜欢

转载自blog.csdn.net/qq_42396168/article/details/105014429
今日推荐