深入理解Java:《Thinking in Java 4th Edition》精髓解析

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:《Thinking in Java 4th Edition》是Bruce Eckel编写的Java经典教程,深入浅出地涵盖了Java语言的各个方面。第四版不仅更新了Java技术,还增加了更多实用示例和详细解释,成为程序员深入学习Java不可或缺的教材。书中内容从面向对象基础到集合框架,再到异常处理、多线程编程、输入/输出流、泛型、反射以及网络编程和JVM内部机制,每部分都有详尽的阐述。中文版的前七章更以中文解读帮助读者更好地理解和吸收这些核心概念,为深入学习Java打下坚实基础。 Thinking In Java 4th Edition

1. 面向对象编程基础

面向对象编程(OOP)是现代编程语言中的一种核心概念,其主要思想是将数据和处理数据的方法封装在对象中,以实现信息隐藏、代码复用和模块化。本章将介绍面向对象编程中的几个核心概念:类和对象、继承、多态以及接口的定义与作用。

类和对象

类是创建对象的模板或蓝图,包含了同一类事物共同的属性和行为。在Java中,我们使用关键字 class 来定义一个类,如下所示:

public class Person {
    // 属性
    private String name;
    private int age;

    // 方法
    public void introduce() {
        System.out.println("My name is " + name + " and I'm " + age + " years old.");
    }
}

对象是类的实例,具有类定义的属性和行为。创建对象的语法如下:

Person person = new Person();
person.name = "Alice";
person.age = 25;
person.introduce();

在这个例子中, person Person 类的一个实例,拥有自己的属性和行为。

继承和多态

继承是面向对象编程的另一个关键特性,它允许我们创建一个新的类(子类),继承另一个类(父类)的属性和方法。这不仅促进了代码的重用,还增强了类之间的层次关系。例如:

public class Student extends Person {
    private String school;

    public void attendClass() {
        System.out.println(name + " is attending class in " + school + ".");
    }
}

多态是指允许不同类的对象对同一消息做出响应的能力。在Java中,多态性主要通过方法重写和接口实现来实现。

接口的定义与作用

接口是Java中的一种引用类型,是完全抽象的,它允许定义一组方法规范,而无需提供这些方法的实现。接口对于实现抽象和多态性非常有用。接口的基本语法如下:

public interface Movable {
    void move();
}

public class Car implements Movable {
    public void move() {
        System.out.println("Car is moving.");
    }
}

通过实现接口 Movable Car 类承诺会提供 move 方法的具体实现,从而保证了多态性。接口在定义API、分离实现与契约以及实现回调机制等方面有着广泛的应用。

2. 基本类型和封装

2.1 数据类型特点及使用场景

在Java编程中,基本数据类型和引用类型是构建程序的基石。理解它们之间的区别对于编写高效的代码至关重要。基本类型直接存储值,而引用类型存储的是指向对象的引用。

2.1.1 基本类型和引用类型的区别

基本类型包括 byte , short , int , long , float , double , boolean , 和 char 。它们的值直接存储在栈内存中,分配和回收速度快,但其值的范围和功能有限。引用类型,如类、接口、数组和枚举,存储的是对象引用,而非对象本身。对象的实例存储在堆内存中,这意味着它们的创建和销毁速度慢于基本类型。

例如,声明一个整数变量并赋值,这通常涉及一个基本类型的操作:

int number = 100;

而在处理对象时,则使用引用类型:

String name = new String("Alice");

这里, name 是一个引用,指向堆内存中由 new String("Alice") 创建的字符串对象。

2.1.2 封装的作用与实现方式

封装是面向对象编程的核心概念之一,它隐藏了对象的内部细节,并提供了访问对象状态的公共接口。封装提供了一种保护机制,防止对象的内部状态被随意访问和修改,从而维护了数据的完整性和安全性。

封装的实现方式通常包括: - 将对象的属性定义为私有( private ); - 提供公共的( public )方法来设置和获取这些私有属性的值。

例如:

public class Person {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

在这个例子中, name 属性被定义为私有,外部代码不能直接访问。相反,通过 getName() setName() 方法进行间接访问和修改。

2.1.3 构造方法和静态块的使用时机

构造方法是类的一种特殊方法,当创建类的新对象时被调用。构造方法可以重载,意味着同一个类可以有多个构造方法,以不同的方式初始化对象。构造方法的名称必须与类名相同,且没有返回类型。

public class Rectangle {
    private int width;
    private int height;

    // 构造方法
    public Rectangle(int width, int height) {
        this.width = width;
        this.height = height;
    }
}

静态块则是在类加载到JVM时执行,并且仅执行一次。它通常用于初始化静态数据,比如静态变量。

public class Utility {
    // 静态块
    static {
        // 初始化代码
    }
}

在使用场景上,构造方法用于对象实例化时的初始化,而静态块用于类级别数据的初始化。

2.2 数据类型转换和运算

2.2.1 自动类型转换与强制类型转换

Java提供了一套类型转换机制,包括自动类型转换和强制类型转换。自动类型转换(隐式转换)发生在较小的数值类型赋值给较大的数值类型时。相反,强制类型转换(显式转换)需要程序员明确指定转换类型。

自动类型转换示例:

int a = 10;
long b = a; // 自动类型转换为long

强制类型转换示例:

double c = 3.14;
int d = (int) c; // 强制类型转换为int,结果为3

在进行强制类型转换时,需要小心,因为可能会导致数据丢失或精度下降。

2.2.2 数值运算、位运算及布尔运算的规则

Java支持的运算包括算术运算、关系运算、逻辑运算等。

算术运算符包括 + (加)、 - (减)、 * (乘)、 / (除)和 % (取模)。关系运算符包括 == (等于)、 != (不等于)、 > (大于)、 < (小于)、 >= (大于等于)、 <= (小于等于),用于比较两个数值。逻辑运算符包括 && (逻辑与)、 || (逻辑或)、 ! (逻辑非),用于布尔值的逻辑运算。

位运算符则包括 & (按位与)、 | (按位或)、 ^ (按位异或)、 ~ (按位取反)、 << (左移)、 >> (右移)和 >>> (无符号右移)。位运算在处理二进制数据和优化算法时非常有用。

2.2.3 运算符优先级及应用实例

运算符优先级决定了表达式中运算执行的顺序。在没有括号的情况下,按照优先级从高到低的顺序执行。例如:

int a = 2 + 3 * 5; // 结果为17,因为乘法先于加法执行

优先级可以通过使用括号 () 来改变:

int a = (2 + 3) * 5; // 结果为25,因为括号内的加法先执行

在实际编程中,合理使用运算符优先级,可以提高代码的可读性和正确性。

在本章节中,我们深入了解了基本类型和封装的特点,数据类型转换与运算的基础知识,并在实际例子中探讨了如何应用这些概念。这些基础知识对于任何想要深入学习Java的开发者来说都是必须掌握的。

3. 集合框架

3.1 List和Set接口及其实现类特性

集合框架是Java编程中用于存储和操作数据集的标准工具。List和Set是Java集合框架中的两个重要接口,它们提供了不同的数据组织方式,每个接口都有其特定的实现类。了解它们的内部结构、性能特点和使用场景对于开发高效的应用程序至关重要。

3.1.1 ArrayList与LinkedList的内部结构与性能对比

ArrayList和LinkedList是List接口的两种主要实现,它们在内部结构和性能方面有着显著的差异。

  • ArrayList 基于动态数组的数据结构,它可以提供快速的随机访问和在列表末尾添加或删除元素的操作。由于ArrayList的元素是连续存储的,因此在插入和删除非尾部元素时可能会涉及到大量的元素迁移,这会导致性能下降。
  • LinkedList 基于链表的数据结构,它维护了节点之间的链式引用,使得在列表任何位置添加或删除元素都非常迅速,因为无需移动元素。然而,LinkedList访问特定索引位置的元素时性能较差,因为它需要从头节点开始遍历链表。

从性能的角度来看,以下是一个简单的比较表格:

| 操作 | ArrayList | LinkedList | |--------------|------------|------------| | add(e) | 快速 | 快速 | | add(e, index)| 较慢 | 快速 | | remove(e) | 较慢 | 快速 | | remove(index)| 较慢 | 快速 | | get(index) | 快速 | 较慢 | | set(index, e)| 快速 | 较慢 |

下面是一个简单的ArrayList添加元素和删除元素的代码示例:

ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
// 删除第二个元素
arrayList.remove(1);

3.1.2 HashSet与LinkedHashSet的存储机制及使用场景

HashSet和LinkedHashSet都实现了Set接口,它们的主要用途是保证元素的唯一性。

  • HashSet 基于HashMap来实现,它不允许存储重复的元素。HashSet的性能较高,特别是在查找元素时,可以提供接近常数时间的性能。但它不保证元素的顺序。
  • LinkedHashSet 是HashSet的子类,它通过维护一个双向链表来保持插入顺序。这意味着元素的迭代顺序与插入顺序相同。LinkedHashSet在插入和删除操作上比HashSet稍慢,因为它需要维护链表结构。

以下是一个简单的HashSet使用示例,展示了添加和删除操作:

HashSet<String> hashSet = new HashSet<>();
hashSet.add("Apple");
hashSet.add("Banana");
hashSet.remove("Apple");

3.1.3 排序与迭代:使用Collections.sort与Iterator

Java集合框架提供了多种工具来对集合元素进行排序和迭代操作。

  • Collections.sort 方法可以对List集合进行排序,其内部使用的是TimSort算法,一种高效的排序算法。它要求List中的元素必须实现Comparable接口,或者在调用时传递一个Comparator。
  • Iterator 是一种迭代器模式的实现,允许在迭代集合时删除元素。它提供了一个hasNext()方法来检查是否还有元素可以迭代,以及一个next()方法来获取下一个元素。

下面是一个使用Collections.sort对自定义对象列表进行排序的示例:

import java.util.*;

class Person implements Comparable<Person> {
    String name;
    int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public int compareTo(Person other) {
        ***pare(this.age, other.age);
    }

    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + '}';
    }
}

public class SortExample {
    public static void main(String[] args) {
        List<Person> people = new ArrayList<>();
        people.add(new Person("Alice", 30));
        people.add(new Person("Bob", 25));
        people.add(new Person("Charlie", 35));

        Collections.sort(people);
        System.out.println(people);
    }
}

在集合框架中,排序和迭代是常用的操作,它们使得处理集合元素更加灵活和高效。理解这些操作的内部机制和最佳实践对于优化应用程序性能至关重要。

4. 异常处理与多线程编程

异常处理是Java编程中不可或缺的一部分,它涉及到程序的健壮性和用户体验。多线程编程允许开发者创建同时执行的多个任务,是实现高并发和并行处理的关键技术。本章节将深入探讨异常处理与多线程编程的各种细节。

4.1 异常分类和自定义异常的创建与使用

4.1.1 Java异常体系结构及运行时异常的特点

Java异常处理机制通过将错误分类,使得程序能够以结构化的方式处理运行时可能发生的错误。Java的异常主要分为两大类:检查型异常(checked exceptions)和非检查型异常(unchecked exceptions)。检查型异常必须在代码中被显式地处理,而非检查型异常则包括运行时异常(RuntimeException)和错误(Error)。运行时异常是那些通常指示编程错误的异常,如空指针异常(NullPointerException)和数组越界异常(ArrayIndexOutOfBoundsException)。它们无需在代码中显式声明,编译器也不会强制要求处理这些异常。

4.1.2 创建和抛出自定义异常的场景与方法

在实际开发过程中,系统可能遇到一些特定的错误情况,标准异常库中可能没有现成的异常类型可以使用。此时,可以通过创建自定义异常来更清晰地表示这些错误。自定义异常通常是通过继承Exception或其子类(推荐继承RuntimeException,如果你不想强制调用者捕获这个异常)来实现的。

下面是一个自定义异常的示例代码:

public class MyCustomException extends Exception {
    public MyCustomException(String message) {
        super(message);
    }
    // 可以添加构造方法和额外的功能
}

使用自定义异常时,可以在可能发生错误的方法中抛出异常:

public void someOperation() throws MyCustomException {
    // 可能触发异常的操作
    if (/* 错误条件 */) {
        throw new MyCustomException("发生了一个自定义错误!");
    }
}

4.1.3 异常捕获的最佳实践和异常处理策略

异常处理的好坏直接影响程序的健壮性和可维护性。一个异常处理的最佳实践包括:

  • 只捕获你能够处理的异常 :避免捕获 Exception Throwable ,这会隐藏程序中可能存在的问题。
  • 记录异常信息 :将异常信息记录到日志文件中,便于问题定位和事后分析。
  • 不要忽略捕获到的异常 :如果异常被忽略,程序的行为可能会变得不可预测。
  • 适当使用finally块 :确保资源被正确关闭,如数据库连接和文件句柄。

异常处理策略包括:

  • 异常链 :如果内部操作抛出了一个异常,可以捕获该异常并抛出一个新的包含原始异常信息的异常。
  • 异常转换 :将技术性的异常转换为业务级别的异常,使客户端代码更容易理解和处理。

4.2 线程创建和同步控制方法

4.2.1 理解Java线程模型和生命周期

Java线程模型支持多线程的创建和执行,每个线程都有自己的生命周期,包括新建、就绪、运行、阻塞和死亡状态。线程的创建可以通过实现Runnable接口或继承Thread类来完成。线程一旦启动,就可以运行,但运行的时机由操作系统的线程调度器决定。

4.2.2 实现线程的方式:继承Thread类与实现Runnable接口

实现Thread类是最简单的创建线程的方式,通过覆盖Thread类的run方法来定义线程执行的操作。

public class MyThread extends Thread {
    @Override
    public void run() {
        // 线程要执行的操作
    }
}

通过实现Runnable接口创建线程可以避免单继承的限制,并且使线程行为更易于复用。

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        // 线程要执行的操作
    }
}

4.2.3 同步机制:synchronized关键字和锁的使用

同步机制是控制并发访问共享资源的一种手段。Java中提供了synchronized关键字来实现同步。当一个线程访问一个对象的synchronized方法时,它将会锁定这个对象。

public class Counter {
    private int count;

    public synchronized void increment() {
        count++;
    }

    public synchronized int getCount() {
        return count;
    }
}

在Java 5及之后的版本中,引入了更细粒度的锁控制机制,例如使用ReentrantLock类,它提供了更多的灵活性和高级特性,比如尝试获取锁的限时操作。

4.3 并发编程高级特性

4.3.1 线程池的使用和优势

线程池是管理一组工作线程的执行单元,它能够有效地重用线程,减少线程创建和销毁的开销,提高程序性能。使用线程池,可以通过创建ExecutorService实例来管理线程。

ExecutorService executorService = Executors.newFixedThreadPool(10);
executorService.execute(new MyRunnable());
executorService.shutdown();

4.3.2 volatile关键字和原子操作

volatile关键字能够保证变量的可见性,即当一个线程修改了这个变量的值,新值对于其他线程来说是立即可见的。但是volatile并不保证操作的原子性,对于复合操作,需要使用Atomic类。

volatile boolean running = true;

public void stop() {
    running = false;
}

public void run() {
    while (running) {
        // 线程执行的操作
    }
}

4.3.3 并发集合类和Map的Concurrent实现

Java提供了专门用于并发环境的集合类,如ConcurrentHashMap、ConcurrentLinkedQueue等。这些集合类内部采用了不同的技术来实现线程安全,如分段锁技术等,相比于同步集合类,它们在并发读写操作时能提供更好的性能。

ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();
map.put("key", "value");
String value = map.get("key");

通过本章节的介绍,我们可以了解到Java中异常处理与多线程编程的详细概念、实践方法和高级特性。掌握这些知识点对于开发高效、稳定的应用程序至关重要。

5. 输入/输出流与泛型编程

在Java编程中,输入/输出流是处理数据输入和输出的基本工具,是与外部世界交互的关键技术之一。另一方面,泛型编程允许程序员编写与数据类型无关的代码,提高了代码的可重用性,同时保证了类型安全。本章将深入探讨输入/输出流的使用方法和泛型编程的概念及其应用。

5.1 输入/输出流:文件操作、字符流、字节流、序列化应用

5.1.1 文件读写操作:使用File和RandomAccessFile类

Java中的文件操作通常涉及到 java.io 包中的类。 File 类是其中最基本的类,用于表示文件和目录路径名的抽象表示形式。 RandomAccessFile 是一个用于读取和写入文件的类,提供了随机访问功能。

File file = new File("example.txt");
try (FileWriter writer = new FileWriter(file)) {
    writer.write("Hello, World!");
} catch (IOException e) {
    e.printStackTrace();
}

在上面的代码中,我们创建了一个 FileWriter 实例来写入文件。注意,使用了try-with-resources语句来自动关闭资源。同样的,我们可以使用 FileReader 来读取文件内容。

RandomAccessFile 提供了一种独特的方式来访问文件。它不仅可以按顺序访问,还可以跳转到文件中的任意位置进行读写操作。

try (RandomAccessFile file = new RandomAccessFile("example.txt", "rw")) {
    file.seek(5); // 跳转到文件中的第6个字节
    file.writeUTF("Java");
}

5.1.2 字符流与字节流的区别和使用场景

在Java I/O中,有两种基本的流类型:字节流和字符流。字节流继承自 InputStream OutputStream ,处理的是原始的字节数据。字符流继承自 Reader Writer ,处理的是字符数据。

字节流适用于处理如图像、音频和视频等二进制数据。字符流适用于处理文本数据,因为它们是基于字符的,并且能更好地处理字符编码问题。

5.1.3 序列化与反序列化的原理和应用

序列化是将对象的状态信息转换为可以存储或传输的形式的过程。在Java中,这通常是通过实现 Serializable 接口来完成的。反序列化则是序列化的逆过程,即将序列化的数据恢复为对象。

import java.io.*;

class User implements Serializable {
    private static final long serialVersionUID = 1L;
    private String name;
    private transient String password; // transient关键字用于标记不需要序列化的字段
    // ... 其他字段和方法
}

public class SerializationExample {
    public static void main(String[] args) {
        User user = new User("Alice", "alice123");
        try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("user.ser"))) {
            out.writeObject(user);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 反序列化示例
        try (ObjectInputStream in = new ObjectInputStream(new FileInputStream("user.ser"))) {
            User newUser = (User) in.readObject();
            System.out.println(newUser.name); // 输出 Alice
            // System.out.println(newUser.password); // password 不会被反序列化
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

在这个例子中, User 类实现了 Serializable 接口,因此可以被序列化。 transient 关键字用于指定不需要序列化的字段。

5.2 泛型概念、通配符使用、类型安全性

5.2.1 泛型的引入背景和基本使用方法

泛型是Java SE 5中的一个新特性,它允许在定义类、接口和方法时使用类型参数(type parameter)。这样,可以创建更通用的代码,可以在使用时指定类型。

public class Box<T> {
    private T t;
    public void set(T t) {
        this.t = t;
    }
    public T get() {
        return t;
    }
}

Box 类使用了泛型类型 T ,可以存储任何类型的对象。

5.2.2 通配符的引入及高级用法:extends和super

Java中的泛型通配符用问号 ? 表示,它用于指定类型参数的上界或下界。 ? extends T 表示这个泛型类型的上界是 T ,而 ? super T 表示这个泛型类型的下界是 T

List<? extends Number> list1 = new ArrayList<Integer>();
List<? super Number> list2 = new ArrayList<Number>();

5.2.3 泛型在集合框架中的应用和类型安全保证

集合框架是Java泛型应用最广泛的领域之一。使用泛型集合类可以避免在运行时进行类型转换,从而提高代码的安全性和可读性。

List<String> stringList = new ArrayList<>();
stringList.add("Hello");
stringList.add("World");
// stringList.add(123); // 编译器错误,类型不匹配

在这个例子中,我们创建了一个 ArrayList<String> ,并添加了字符串元素。尝试添加非字符串元素将会在编译时期报错,这是泛型提供的类型安全保证。

在本章中,我们探讨了Java输入/输出流的文件操作、字符流与字节流的区别,以及序列化与反序列化的原理和应用。同时,我们也深入学习了泛型编程,包括泛型的概念、通配符的高级用法以及泛型在集合框架中的应用。掌握这些知识对于编写健壮、可维护的Java代码至关重要。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:《Thinking in Java 4th Edition》是Bruce Eckel编写的Java经典教程,深入浅出地涵盖了Java语言的各个方面。第四版不仅更新了Java技术,还增加了更多实用示例和详细解释,成为程序员深入学习Java不可或缺的教材。书中内容从面向对象基础到集合框架,再到异常处理、多线程编程、输入/输出流、泛型、反射以及网络编程和JVM内部机制,每部分都有详尽的阐述。中文版的前七章更以中文解读帮助读者更好地理解和吸收这些核心概念,为深入学习Java打下坚实基础。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

写在前面的话 引言 1. 前提 2. Java的学习 3. 目标 4. 联机文档 5. 章节 6. 练习 7. 多媒体 8. 源代码 9. 编码样式 10. Java版本 11. 课程和培训 12. 错误 13. 封面设计 14. 致谢 第1章 对象入门 1.1 抽象的进步 1.2 对象的接口 1.3 实现方案的隐藏 1.4 方案的重复使用 1.5 继承:重新使用接口 1.5.1 改善基础类 1.5.2 等价和类似关系 1.6 多形对象的互换使用 1.6.1 动态绑定 1.6.2 抽象的基础类和接口 1.7 对象的创建和存在时间 1.7.1 集合与继承器 1.7.2 单根结构 1.7.3 集合库与方便使用集合 1.7.4 清除时的困境:由谁负责清除? 1.8 违例控制:解决错误 1.9 多线程 1.10 永久性 1.11 Java和因特网 1.11.1 什么是Web? 1.11.2 客户端编程 1.11.3 服务器端编程 1.11.4 一个独立的领域:应用程序 1.12 分析和设计 1.12.1 不要迷失 1.12.2 阶段0:拟出一个计划 1.12.3 阶段1:要制作什么? 1.12.4 阶段2:开始构建? 1.12.5 阶段3:正式创建 1.12.6 阶段4:校订 1.12.7 计划的回报 1.13 Java还是C++? 第2章 一切都是对象 2.1 用句柄操纵对象 2.2 必须创建所有对象 2.2.1 保存在什么地方 2.2.2 特殊情况:主类型 2.2.3 Java中的数组 2.3 绝对不要清除对象 2.3.1 作用域 2.3.2 对象的作用域 2.4 新建数据类型:类 2.4.1 字段和方法 2.5 方法、自变量和返回值 2.5.1 自变量列表 2.6 构建Java程序 2.6.1 名字的可见性 2.6.2 使用其他组件 2.6.3 static关键字 2.7 我们的第一个Java程序 2.8 注释和嵌入文档 2.8.1 注释文档 2.8.2 具体语法 2.8.3 嵌入 2.8.4 @see:引用其他类 2.8.5 类文档标记 2.8.6 变量文档标记 2.8.7 方法文档标记 2.8.8 文档示例 2.9 编码样式 2.10 总结 2.11 练习 第3章 控制程序流程 3.1 使用Java运算符 3.1.1 优先级 3.1.2 赋值 3.1.3 算术运算符 3.1.4 自动递增和递减 3.1.5 关系运算符 3.1.6 逻辑运算符 3.1.7 按位运算符 3.1.8 移位运算符 3.1.9 三元if-else运算符 3.1.10 逗号运算符 3.1.11 字串运算符 3.1.12 运算符常规操作规则 3.1.13 造型运算符 3.1.14 Java没有“sizeof” 3.1.15 复习计算顺序 3.1.16 运算符总结 3.2 执行控制 3.2.1 真和假 3.2.3 反复 3.2.6 中断和继续 3.2.7 切换 3.3 总结 3.4 练习 第4章 初始化和清除 4.1 由构建器保证初始化 4.2 方法过载 4.2.1 区分过载方法 4.2.2 主类型的过载 4.2.3 返回值过载 4.2.4 默认构建器 4.2.5 this关键字 4.3 清除:收尾和垃圾收集 4.3.1 finalize()用途何在 4.3.2 必须执行清除 4.4 成员初始化 4.4.1 规定初始化 4.4.2 构建器初始化 4.5 数组初始化 4.5.1 多维数组 4.6 总结 4.7 练习 第5章 隐藏实施过程 5.1 包:库单元 5.1.1 创建独一无二的包名 5.1.2 自定义工具库 5.1.3 利用导入改变行为 5.1.4 包的停用 5.2 Java访问指示符 5.2.1 “友好的” 5.2.2 public:接口访问 5.2.3 private:不能接触 5.2.4 protected:“友好的一种” 5.3 接口与实现 5.4 类访问 5.5 总结 5.6 练习 第6章 类再生 6.1 合成的语法 6.2 继承的语法 6.2.1 初始化基础类 6.3 合成与继承的结合 6.3.1 确保正确的清除 6.3.2 名字的隐藏 6.4 到底选择合成还是继承 6.6 递增开发 6.7 上溯造型 6.7.1 何谓“上溯造型”? 6.8 final关键字 6.8.1 final数据 6.8.2 final方法 6.8.3 final类 6.8.4 final的注意事项 6.9 初始化和类装载 6.9.1 继承初始化 6.10 总结 6.11 练习 第7章 多形性 7.1 上溯造型 7.1.1 为什么要上溯造型 7.2 深入理解 7.2.1 方法调用的绑定 7.2.2 产生正确的行为 7.2.3 扩展性 7.3 覆盖与过载 7.4 抽象类和
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值