《Java黑皮书基础篇第10版》 第11章【笔记】

第十一章

11.1 引言
11.2 父类和子类

子类继承它的父类中所有可访问的数据域和方法(不包括private修饰符修饰的方法和构造方法)

11.3 使用super关键字

关键字super指代父类,用于调用父类中的普通方法和构造方法

对于调用构造方法:

必须使用super(), 而且这个调用必须是构造方法的第一条语句

构造方法链:在Java中,任何class的构造方法,第一行语句必须是调用父类的构造方法。如果没有明确地调用父类的构造方法,编译器会帮我们自动加一句super();。任何情况下,使用构造方法构造一个类的实例,在执行构造方法内的代码之前(this()除外,如果有this(),就先执行this,调用类内部的其他构造方法),会沿着继承链调用所有父类的构造方法,这就是构造方法链。调用到最后一个父类时,再按原路返回依次执行调用过的构造方法的方法体。

因此,一般情况下,最好能为每个类定义一个无参构造方法,避免错误

对于调用普通方法:

使用super.方法名(参数);

11.4 方法重写

要重写一个方法,需要在子类中使用和父类一样的签名(即方法名+参数列表)以及一样的返回值类型来对该方法进行定义。

不可以重写private修饰的方法

11.5 方法重写与重载

方法重写具有相同的返回值类型、方法名和参数列表;方法重载具有相同的返回值类型(通常情况下)和方法名,但是不同的参数列表

方法重写发生在通过继承的不同类中;方法重载可以发生在同一个类中,也可以发生在通过继承的不同类中。因此,我们使用@Override来判断其标注的方法是否重写了父类的一个方法,来判断这是不是一个合法的方法重写。

11.6 Object类及其toString()方法

Java中的所有类都继承自java.lang.Object类

在Object类中有一个toString()方法,默认情况下,它返回一个由该对象所属的类名 、@符号以及该对象十六进制形式的内存地址组成的字符串,例如Loan@15037e5。我们可以通过重写这个方法来获得更有意义的信息。

11.7 多态
Person p = new Student();

多态意味着父类型的变量可以引用子类型的对象。

11.8 动态绑定
Person p = new Student();

在Java中,实例方法的调用是基于运行时对对象类型(new Student();)的动态调用,并不是基于引用变量(Person p)的类型

11.9 对象转换和instanceof运算符

对象可以进行向上转型和向下转型

Person p1 = new Student(); // upcasting, ok
Person p2 = new Person();

//p1表示Student实例,可以转型
Student s1 = (Student) p1; // ok
//p2表示Person实例,不能把父类Person变成子类Student
Student s2 = (Student) p2; // runtime error! ClassCastException!

instanceof实际上判断一个变量所指向的实例是否是指定类型,或者这个类型的父类,例如

Person p = new Person();
//判断一个变量p所指向的实例new Person()是否是指定类型Person,或者是Person()的父类
System.out.println(p instanceof Person); // true
System.out.println(p instanceof Student); // false

Student s = new Student();
//判断一个变量s所指向的实例new Student()是否是指定类型Student,或者是Student()的父类Person
System.out.println(s instanceof Person); // true
System.out.println(s instanceof Student); // true

你可能会奇怪为什么必须进行类型转换。变量 myObject 被声明为 Object。声明类型 决定了在编译时匹配哪个方法。使用 myObject.getDiameter() 会引起一个编译错误,因为 Object类没有getDiameter方法。编译器无法找到和myObject.getDiameter()匹配的方法。 所以,有必要将 myObject 转换成 Circle 类型,来告诉编译器 myObject 也是 Circle 的一个 实例。

Object myObject = new Circle();

if (myobject instanceof Circle) {
	System.out.println("The circle diameter is " +
  	((Circle)myobject).getDiameter());
}

对象成员访问运算符(.)优先于类型转换运算符。使用圆括号保证在点运算符(•)之前进行类型转换,例如:

((Circle)object).getArea();

转换基本类型值创建一个新的值,而转换一个对象引用不会创建一个新的对象

int age = 45;
byte newAge = (byte)age; // A new value is assigned to newAge

Object o = new Circle();
Circle c = (Circle)o; // Refenerce Variable o and c point to the same object
11.10 Object 类的 equals 方法

如同toString()方法,equals(Object)方法是定义在Object类中的另外一个 有用的方法。

11.11 ArrayList 类

Java 提供 ArrayList 类来存储不限定个数的对象。

11.12 对于列表有用的方法

可以复制Array中的元素新建一个ArrayList,也可以把ArrayList中的元素复制到Array中

ArrayList提供了很多有用的方法,例如排序,打乱数组,算最大值最小值等

11.13 示例学习:自定义栈类
11.14 protected数据和方法

经常需要允许子类访问定义在父类中的数据域或方法,但不允许非子类访问这些数据域 和方法。可以使用关键字 Protected 完成该功能。

11.15 防止扩展和重写

一个被final修饰的类和方法都不能被扩展。被final修饰的数据域是一个常数。

### 回答1: 11.6题要求我们实现一个简单的Java虚拟机,可以执行一些简单的Java程序。具体来说,我们需要实现以下几个部分: 1. 读取Java字节码文件,将其解析成指令序列。 2. 实现一个虚拟机栈,用于存储局部变量和操作数栈。 3. 实现指令集,包括常量加载、算术运算、比较运算、跳转等指令。 4. 执行指令序列,模拟Java程序的执行过程。 在实现过程中,我们需要注意一些细节问题,比如指令的操作数类型、栈帧的管理、异常处理等。此外,我们还需要考虑性能问题,比如如何优化指令的执行速度、如何减少内存占用等。 总之,实现一个Java虚拟机是一项非常复杂的任务,需要深入理解Java语言和计算机系统的原理。但是,通过这个练习,我们可以更好地理解Java程序的执行过程,提高我们的编程能力。 ### 回答2: Java黑皮1111.6主要探讨了Java中的异常处理机制,以及如何自定义异常。本节的核心知识点包括: 1. 异常的概念:异常是在程序执行期间发生的错误或其他意外情况,它打断了正常的程序执行流程。 2. 异常的分类:Java中将异常分为Checked异常和Unchecked异常。Checked异常在编译期间就必须捕获处理,否则编译器会提示错误。Unchecked异常则不需要在编译期间捕获,但程序在运行时会抛出异常。 3. 异常处理机制:Java提供了try-catch语句用于捕获和处理异常。try块中放置可能会抛出异常的代码,catch块中处理异常的代码。 4. 自定义异常:Java允许我们自定义异常类,继承自Exception或RuntimeException,也可以添加自己的字段、方法等。 这一节的课后题主要是通过代码实践来加深对异常处理机制的理解,以及练习自定义异常类。有一道比较经典的题目是编写一个自定义异常类,并在程序中抛出这个异常。这个题目的思路可以参考以下步骤: 1. 创建一个自定义异常类,继承自Exception或RuntimeException。 2. 在构造方法中传入异常信息,然后调用父类的构造方法。 3. 在程序的某个地方,使用throw关键字抛出自定义异常。 4. 在主程序中使用try-catch语句捕获自定义异常,在catch块中处理异常。 例如,我们可以创建一个自定义异常类MyException,并在程序的某个地方抛出这个异常: class MyException extends RuntimeException{ public MyException(String message){ super(message); } } public class Main{ public static void main(String[] args){ try{ throw new MyException("这是一个自定义异常"); }catch(MyException e){ System.out.println("捕获到自定义异常:" + e.getMessage()); } } } 在这个例子中,我们创建了一个自定义异常类MyException,它继承自RuntimeException。在程序的try块中,我们使用throw关键字抛出这个异常。在主程序中,我们使用try-catch语句捕获这个自定义异常,并在catch块中处理异常并输出异常信息。 总的来说,Java黑皮1111.6是一个非常重要的节,掌握异常处理机制和自定义异常类的知识对于Java程序开发至关重要。在实际的开发中,我们需要根据实际情况进行异常处理,使程序更加健壮和可靠。 ### 回答3: 11.6题是要求实现一个基于协程(Coroutine)的简单HTTP服务器。协程是一种比线程更轻量级的并发机制,可以在单个线程中实现多个协程的交替执行,类似于CPU在操作系统中的任务切换。HTTP服务器是指接受HTTP请求并返回HTTP响应的程序或服务。 在实现基于协程的HTTP服务器时,我们需要使用Java的协程库,比如Quasar,ByteBuddy或Kilim。在这个服务器中,每个HTTP请求都被视为一个协程,并且服务器需要实现以下功能: 1. 监听并接受HTTP请求:服务器需要启动一个监听端口,以接受客户端的HTTP请求,并将其转变为协程来处理。 2. 解析HTTP请求:对于每个接受的HTTP请求,服务器需要解析其请求头和主体,以确定请求类型、请求路径、请求方法等信息。 3. 处理HTTP请求:服务器需要根据请求的类型和路径,决定如何处理每个HTTP请求。常见的处理方式是返回文件内容、执行代码、跳转到其它页面等。在协程处理HTTP请求时,服务器可以暂停当前协程,等待文件读取、代码执行等耗时操作完成后,再恢复当前协程继续执行。 4. 返回HTTP响应:服务器需要将处理结果封装成HTTP响应,包括响应头和响应主体内容,并将其发送回客户端。 在实现这个服务器时,需要注意以下几点: 1. Java协程库的选择:Java提供了不同的协程库,每个库有不同的优缺点。要根据实际需求选择适合的协程库,并掌握其基本使用方法。 2. HTTP请求的解析:需要熟悉HTTP协议的请求格式和规范,以正确解析每个请求,并提取需要的信息。 3. 耗时操作的处理:在处理HTTP请求时,可能会遇到需要,等待文件读取、代码执行等耗时操作。要注意在这些操作上暂停当前协程,并在操作完成后恢复协程的执行。 4. 程序的安全性:在实现HTTP服务器时,要注意相关的安全问题,比如防止跨站脚本(XSS)攻击、拒绝服务(DOS)攻击、SQL注入等。 总之,基于协程实现HTTP服务器是一项复杂的工作,需要综合掌握HTTP协议、Java协程库、耗时操作处理、程序安全等多个方面的知识。如果熟练掌握这些技能,就可以实现高效、安全、稳定的HTTP服务器,满足不同场景下的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值