点击返回标题->23年Java期末复习-CSDN博客
选择题考察内容为——
- 构造函数的描述,
- 在文件中写入字符而不是字节选用什么类,
- java源文件import, class定义以及package的顺序,
- 静态成员变量作用域,
- 非抽象子类的接口实现,
- 异常抛出处理,
- 创建新线程,
- 重写和重载的关系,
- 线程生命周期,
- final关键字理解,
- 包的理解,
- 对象多态性体现,
- Socket创建对象
上面这一段是老师强调的选择题部分考题的范围,可以理解为“考纲最高指示”,本篇就对这个“考纲”进行重点内容的解读(而不是系统性地讲的事无巨细,否则不如去看其它博客了是吧,其中我认为重要的内容会黑色加粗、十分重要的会用红色加粗字体标注。但不代表没这样做的就不重要,毕竟作为精华提炼出来写在这里的都是重点了。)
Java构造函数是一种特殊的方法,它用于在创建对象时初始化对象的成员变量。构造函数的定义方式与普通方法相似,但没有返回类型,并且与类名相同。
以下是构造函数的描述规则和特点:
1. 构造函数的名称必须与所在类的名称完全相同。
2. 构造函数没有返回值类型,包括void(void是空,空不是没有,空也是返回值类型!)。
3. 构造函数可以有参数,也可以没有参数(习惯称前者为有参构造,后者为无参构造)。当没有显示定义构造函数时,Java会提供一个默认的无参构造函数,如果显示定义了构造函数,那么默认的构造函数将不再自动生成。
4. 如果一个类中有多个构造函数,在创建对象时根据传入的参数个数及类型来确定使用哪个构造函数进行初始化。(4其实是构造方法重载的现象)
5. 构造函数可以进行一些初始化操作,例如给成员变量赋初值、执行其他方法等。
6. 构造函数不能被直接调用,只能在创建对象时隐式地调用。7.在子类的构造函数中,可以用super关键字调用父类的构造函数,且必须写在子类构造函数的第一行。
8.当子类继承父类时,如果子类的构造函数没有任何super调用的语句,那么会隐式存在一句"super()"代码去调用父类的无参构造函数。
9. 当子类继承父类时,如果父类中有一个带参数的构造函数,则需要在子类构造函数中使用super关键字来显式调用父类的构造函数,并将参数传递给父类。总结:构造函数的作用是为对象的成员变量赋初始值,确保对象在创建时处于合理的状态。通过合理使用构造函数,可以提高程序的可读性和可维护性。
写入字符采用String类型,String类是Java中的一个引用数据类型,用于表示文本字符串。使用
String
类可以将文本数据写入文件中,而不是字节数据。
以下是一个简单的示例代码,演示如何使用String类将文本写入文件中:
import java.io.FileWriter;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
String text = "Hello, world!";
try {
FileWriter writer = new FileWriter("output.txt");
writer.write(text);
writer.close();
System.out.println("Text written to file successfully.");
} catch (IOException e) {
System.err.println("Error writing to file: " + e.getMessage());
}
}
}
在Java源文件中,通常按照以下顺序组织import语句、class定义和package语句:
- package语句:用于指定当前源文件所属的包,位于文件最顶部。
- import语句:用于引入需要使用的其他类或包,如果有很多import语句导入的是同一个包下的不同类,则可以使用通配符
*
来引入整个包。- class定义:紧随import语句之后,是类的定义部分。它包含了该源文件中要实现的类的具体代码。
代码示例:
Java静态成员变量的作用域是在Java中定义的,它意味着该变量可以在类的所有方法中访问,包括静态方法。
静态成员变量通常用于存储类级别的数据,例如共享的配置信息或常量值。它们可以被类的所有实例共享,并且不需要创建类的实例就可以访问它们。
静态成员变量在Java中具有以下特点:
- 它们属于类本身,而不是类的任何特定实例。
- 它们可以在类的任何方法中访问,包括静态方法。
- 它们可以被多个对象共享,并且不会因为创建了类的实例而创建多个副本。
- 它们的作用域限制在类中,不能在类的外部直接访问,但可以间接访问(类名.静态成员)。
下面示例展示了如何访问类内外的静态成员:
Java中,非抽象子类可以通过实现接口来实现接口的方法。具体步骤如下:
1. 定义一个接口(interface):在 Java 中,接口是一种约定,它定义了一组方法声明,而不提供方法的实现(也不允许存在方法体,就算只写了一对花括号也不行!)。
public interface MyInterface { void method1(); void method2(); //错误的写法: //void method3(){} }
2. 创建一个非抽象子类(class)并实现接口:使用 `implements` 关键字,让该类实现接口中的方法。
public class MyClass implements MyInterface { @Override public void method1() { // 实现method1的代码逻辑 } @Override public void method2() { // 实现method2的代码逻辑 } }
3. 在子类中实现接口方法:通过 `@Override` 注解来标记子类中对接口方法的实现,确保方法签名与接口中的方法一致。
4. 可以通过创建子类的实例对象,来调用接口中的方法。
MyClass myObject = new MyClass(); myObject.method1(); myObject.method2();
上述代码示例中的 `method1` 和 `method2` 都是抽象方法,需要根据具体需求在子类中进行实现。
接口常考细节(移步本篇学习->Java继承(extends)下-CSDN博客):
- 接口中无任何修饰符的变量默认是public static final修饰的,也就是说->接口中的变量默认是全局常量
- 接口中无任何修饰符的方法默认是public abstract修饰的,也就是说->接口中的方法默认是抽象方法
- public接口中的变量和方法默认是public权限的(测试发现也只能是public权限,否则怎么被继承和实现?),对于一般public类来说->变量和方法默认是default修饰的
笔者暂时能想到的是以下这些考点,如果你不放心可以移步去系统性的学习->
Java异常-CSDN博客
try..catch...finally语句
①在异常处理中,若try中的代码可能产生多种异常则可以对应多个catch语句,若catch中的参数类型有父类子类关系,此时应该将子类放在前面,父类放在后面。(子前父后)
②在异常处理中,有try语句不一定要出现catch语句,也可以是try...finally的组合。
throw和throws关键字
声明异常的关键字是throws,抛出异常的关键字是throw。(常考的易混淆点)
异常类声明
Java语言中的所有异常类都是java.lang.Throwable的子类。
感觉全都很重要的笔者抓不到重点,建议直接看这篇->
多线程的实现方式-CSDN博客
在英文上的区别:重写是override,重载是overload
重写:指的是在继承(extends)关系中子类对父类方法覆写的操作,或者实现(implements)关系中派生类对接口方法覆写的操作。
要求重写的方法与被重写的方法返回值类型和形参都不能改变。即外壳不变,核心重写!
重载:指的是为避免实现多个具有相同功能、但细节大同小异的方法时,从而定义好几个不同名字的方法导致维护成本提高的情况出现,所采取的策略,即方法重载。
要求互相重载的方法拥有相同的返回值类型,但参数列表必须不同,其中参数列表是区分不同重载方法的核心。
欲系统性学习见本篇->线程的生命周期及其六种状态的转换 - 知乎 (zhihu.com)
线程的5大状态
- 新建状态(NEW):新创建一个线程对象。
- 就绪状态(RUNNABLE):线程对象创建后,调用该对象的start()方法。该状态的线程等待被线程调度选中,获取CPU的使用权。
- 运行状态(RUNNING):就绪状态(RUNNABLE)的线程获取CPU时间片开始执行程序代码。
- 阻塞状态(BLOCKED):阻塞状态是指线程因为某种原因让出了CPU使用权,直到线程再次进入就绪状态(RUNNABLE),等待再次获取CPU时间片进入运行状态。
- 死亡状态(DEAD):run方法正常退出而自认死亡或者异常终止run方法导致线程结束。
final 关键字是什么?
final 在 Java 中是一个保留的关键字,可以声明成员变量、方法、类等。一旦用final修饰某个引用,你将不能改变这个引用了,编译器会检查代码,比如你如果试图修改final变量的值的话,编译器会直接报编译错误。
final 变量:
final修饰的变量不可被重新赋值,因此final变量经常和 static 关键字一起使用,作为常量。
final int a = 10; a = 20;//报错:无法将值赋给 final 变量
final 方法:
final修饰的方法不允许在派生类中进一步被覆写。
final 类:
final修饰的类不允许被继承,final类的功能通常是比较完整的,所以用final修饰表明它不需要被派生类来完善。
final关键字的好处:
- final 关键字提高了性能,JVM 和 Java 应用都会缓存 final 变量
- final 变量可以安全的在多线程环境下进行共享,而不需要额外的同步开销
欲系统性学习见本篇->Java 包(package) | 菜鸟教程 (runoob.com)
为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间。
包的作用
1、把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用。
2、如同文件夹一样,包也采用了树形目录的存储方式。同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。因此,包可以避免名字冲突。
3、包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类。
import 关键字
为了能够使用某一个包的成员,我们需要在 Java 程序中明确导入该包。
在 Java 中,import 关键字用于导入其他类或包中定义的类型,以便在当前源文件中使用这些类型。
import 关键字用于引入其他包中的类、接口或静态成员,它允许你在代码中直接使用其他包中的类,而不需要完整地指定类的包名。
在 java 源文件中 import 语句必须位于 Java 源文件的头部,其语法格式为:
import package1[.package2…].(classname|*);
比如:
import java.util.ArrayList;
如果在一个包中,一个类想要使用本包中的另一个类,那么该包名可以省略。
可以使用import语句来引入一个特定的类,比如GUI中常用的JFrame类:
这样,你就可以在当前源文件中直接使用swing类的方法、变量或常量。
import javax.swing.JFrame;
也可以使用通配符 * 来引入整个包或包的子包,比如GUI中常用的swing包:
这样,你可以导入javax.swing包中的所有类,从而在当前源文件中使用该包中的任何类的方法、变量或常量。注意,使用通配符 * 导入整个包时,只会导入包中的类,而不会导入包中的子包。
import javax.swing.*;
多态是指一个类可以表现出多种形态(继承父类或实现接口而引申出多个形态的派生类)。
这一块的考点主要是类的向上、向下转型的细节。这一部分建议要重点地、系统地看一下,见本篇->Java多态-CSDN博客
向上转型的对象——
- 调用的变量是父类中的变量,且父类中必须有该变量,否则编译报错
- 调用的方法是子类中的方法,且该方法一定是从父类中继承过来的(可重写)
- 不能调用子类中独有的方法(这一点和上一点相互照应)!
- 自编顺口溜(*^_^*)->"变量只用老子的,方法先看儿子的,儿子独有的不用"
向下转型必须先出现向上转型,所以一定先包含向上转型的语法格式:
- 父类类型 上转型对象1 = new 子类类型A();//这一行先是向上转型
- 子类类型A 下转型对象 = (子类类型A)上转型对象1;
注意点:
必须先向上转型,子类类型A 子类对象 = (子类类型A)new 父类类型();//这种写法是错误的,因为右边new出来的对象没有经过向上转型
第2句的括号(子类类型A)不可以省略
(可以理解为把大范围数据类型赋值给小范围数据类型,如把int类型变量i赋值给short类型变量s,
即:
int i = 10;
short s = (short)i;//这个括号显式强转在Java中是不可省略的!
)
第2句的括号(子类类型A)必须和第一句的new 子类类型A对应,这很好理解->假如第一句是Dog类示例化的对象向上转型成Animal类,那么第二句也得是向下转型为Dog类而不是Cat类或Rabbit类(物种突变!?)
这个是Java网络编程的知识点,明确只会出现在选择题部分中,在讲到这部分时,曾暗示考题可能就出现在下面这部分,多的我就不说了。
Socket(String host, int port)
使用该构造方法在创建Socket对象时,会根据参数去连接在指定地址和端口上运行的服务器程序,其中参数host接收的是个字符串类型的IP地址。
Socket(lnetAddress address, int port)该构造方法在使用上与第二个构造方法类似,参数address用于接收一个InetAddress类型的对象,该对象用于封装一个IP地址。