java复习题
-
什么是静态变量/成员变量/局部变量?有何性质?
- 静态变量是在程序运行期间保持其值不变的变量。它们通常与类或函数关联,而不是与类的实例或函数的调用相关联。
- 成员变量是类或结构体中声明的变量,它们用于描述对象的属性。每个类的实例都有自己的成员变量。
- 局部变量是在函数、方法或代码块内声明的变量,其作用范围仅限于包含它们的代码块。
-
什么是 overload 和 override?有什么区别?
-
overload(重载)
- 定义: 重载是指在同一个类中可以定义多个同名的方法,但这些方法具有不同的参数列表(类型、个数或顺序)。
- 作用: 通过方法的重载,可以让同一个类的不同方法执行类似的操作但处理不同类型的数据或不同数量的参数。
-
override(重写)
- 定义: 覆盖是指在子类中重新定义父类中已经存在的方法,要求方法名、返回类型和参数列表都相同。
- 作用: 通过覆盖,子类可以提供自己特定的实现,而不改变方法的签名。覆盖通常涉及到继承和多态的概念。
-
区别
-
重载(Overload):
- 发生在同一个类中。
- 方法名相同,但参数列表不同。
- 编译器根据方法的参数列表选择调用哪个方法。
-
覆盖(Override):
- 发生在父类和子类之间。
- 方法名、返回类型和参数列表相同。
- 提供了子类对父类方法的重新实现,实现了多态性。
-
-
-
public、protected、default、private 成员变量的访问权限
-
Public(公共):
- 访问范围: 公共成员对于所有类都是可见的,无论它们是同一包中的还是不同包中的。
-
Protected(受保护):
- 访问范围: 受保护成员对于同一包中的类以及继承该类的子类可见。
-
Default(默认,包级别访问):
- 访问范围: 默认访问级别是指不使用任何修饰符,成员对于同一包中的类可见。
-
Private(私有):
- 访问范围: 私有成员仅对声明它们的类可见,不对任何其他类可见。
-
-
在异常处理的过程中,try,catch 和 finally 各有什么作用
-
try:
- 作用: try 用于包含可能引发异常的代码块。在 try 块中放置可能导致异常的代码,例如可能抛出异常的方法调用或其他风险操作。
-
catch:
- 作用: catch 用于捕获并处理 try 块中抛出的异常。它包含一个参数,该参数是捕获到的异常的类型,可以用于进一步处理异常或提供相关信息。
-
finally:
- 作用: finally 用于指定一段代码,无论是否发生异常都会执行。通常用于执行清理工作,例如释放资源(关闭文件、数据库连接等)
- 在完整的异常处理中,try 和 catch 是必须的,而 finally 是可选的。 finally 块通常用于确保资源的释放或清理工作,以便在发生异常时不会导致资源泄漏。
-
-
什么是继承/封装/多态?
-
继承(Inheritance):
- 定义: 继承是一种机制,允许一个类(子类/派生类)基于另一个类(父类/基类)的定义来构建自己的定义。子类继承了父类的属性和方法,可以使用并扩展它们,同时可以定义自己的新属性和方法。
-
封装(Encapsulation):
- 定义: 封装是将数据和方法进行组合,并限制对数据的直接访问,通过公共的方法提供对数据的操作。通过将实现细节隐藏起来,封装可以实现信息隐藏和保护对象状态的目的。
-
多态(Polymorphism):
- 定义: 多态是指相同的操作或方法在不同的对象上有不同的行为。在面向对象编程中,多态可以通过方法重载和方法覆盖实现。
-
-
请解释 this/super 关键字的使用方法
-
this 关键字:
- 用途: this 关键字用于引用当前对象的实例,通常用于区分实例变量和方法参数之间的名称冲突,或者在构造方法中调用其他构造方法。
-
super 关键字:
- 用途: super 关键字用于引用父类的实例或调用父类的方法。它在子类中使用,用于访问父类的成员或调用父类的构造方法。
-
-
说明抽象类和接口有什么区别
-
定义和结构:
- 抽象类: 抽象类是一个类,可以包含抽象方法和具体方法。它可以有构造方法,字段(成员变量),普通方法,也可以包含抽象方法。
- 接口: 接口是一种纯粹的抽象概念,它只包含抽象方法和常量。在 Java 8 及更高版本中,接口可以包含默认方法和静态方法。
-
继承和实现:
- 抽象类: 一个类只能继承一个抽象类,使用关键字 extends。
- 接口: 一个类可以实现多个接口,使用关键字 implements。
-
构造方法:
- 抽象类: 抽象类可以有构造方法,用于初始化实例变量等。
- 接口: 接口不能有构造方法。
-
成员变量:
- 抽象类: 可以包含实例变量,字段,静态变量等。
- 接口: 可以包含常量(静态 final 变量),但不能包含实例变量。
-
访问修饰符:
- 抽象类: 抽象类的方法可以有各种访问修饰符(public、protected、default、private)。
- 接口: 接口的方法默认为 public,并且字段默认为 public static final。
-
-
final 关键字的作用
-
不可变类:
- 作用: 当应用于类时,final 使得类成为不可变类,即类的实例状态不能被修
-
不可变变量:
- 作用: 当应用于变量时,final 使得变量成为常量,一旦赋值后,其值不能被修改。
-
不可变方法:
- 作用: 当应用于方法时,final 使得方法不能被子类重写。
-
不可继承的类:
- 作用: 当应用于类时,final 使得类不能被继承。
-
不可修改的引用变量:
- 作用: 当应用于引用变量时,final 使得引用变量不能再指向其他对象,但不影响被引用对象的可变性。
-
-
实现多线程的方法
-
继承 Thread 类:
- 创建一个类,继承 Thread 类。
- 重写 run() 方法,该方法包含线程的执行代码。
- 创建该类的实例,调用 start() 方法启动线程。
-
实现 Runnable 接口:
- 创建一个类,实现 Runnable 接口。
- 实现 run() 方法,该方法包含线程的执行代码。
- 创建该类的实例,将其传递给 Thread 类的构造方法,并调用 start() 方法启动线程
-
-
列举 Java 中常用的字节输入流和字节输出流并说明其特点,至少 3 对
-
FileInputStream 和 FileOutputStream:
- 特点:
- FileInputStream 用于从文件中读取字节,FileOutputStream 用于向文件中写入字节。
- 适用于处理文件的输入和输出。
- 可以通过构造方法指定文件路径或File对象。
- 读取和写入的单位是字节。
- 特点:
-
ByteArrayInputStream 和 ByteArrayOutputStream:
- 特点:
- ByteArrayInputStream 用于从内存中的字节数组读取数据,ByteArrayOutputStream 用于将数据写入内存中的字节数组。
- 适用于在内存中操作字节数组。
- 不需要关闭,因为基于内存的操作不会引起I/O异常。
- 特点:
-
BufferedInputStream 和 BufferedOutputStream:
- 特点:
- BufferedInputStream 和 BufferedOutputStream 是装饰器流,它们可以提供缓冲区,提高读取和写入的效率。
- 适用于对输入输出流进行缓冲操作,减少对文件或网络的频繁访问。
- 可以通过构造方法传递其他字节输入输出流来包装。
- 特点:
-
-
多线程中 start 方法和 run 方法分别有什么作用?
-
start() 方法:
- 作用: start() 方法用于启动一个新线程,并让新线程执行相应的 run() 方法。
- 行为: 调用 start() 方法将创建一个新的线程,并在新线程中调用 run() 方法。这样,run() 方法将在新线程中并行执行,而不是在当前线程中顺序执行。
-
run() 方法:
- 作用: run() 方法是线程的执行体,包含了线程要执行的代码。
- 行为: 直接调用 run() 方法不会创建新线程,而是在当前线程中执行 run() 方法的代码。这种方式不会实现多线程的并发执行,而只是在当前线程中顺序执行 run() 方法的代码。
- 总的来说,start() 方法用于启动一个新线程,让新线程并发执行 run() 方法的代码,而 run() 方法只是普通的方法调用,不会创建新线程,只会在当前线程中执行 run() 方法的代码。在实现多线程时,通常使用 start() 方法来启动新线程
-
-
简述 Java 中的异常处理机制的简单原理和应用
-
异常简单原理:
- 当在程序执行过程中发生异常时,Java会创建一个异常对象,该对象包含异常的类型、详细信息和堆栈跟踪等信息。
- 异常对象被抛出(thrown),此时程序的正常执行流程被中断。
- 异常对象会被传递给调用栈中的上一级方法,直至找到合适的 catch 块捕获并处理异常,或者传递到顶层的异常处理器(通过 Thread.setDefaultUncaughtExceptionHandler 设置)。
-
应用:
-
try-catch 块:
- try 块中包含可能抛出异常的代码。
- catch 块用于捕获并处理 try 块中的异常。一个 try 块可以有多个 catch 块,每个 catch 块捕获一种异常类型。
- catch 块中的代码用于处理异常,可以输出错误信息、进行日志记录、或采取其他适当的处理措施。
-
throw 关键字:
- throw 用于手动抛出异常对象。程序员可以使用 throw 关键字在代码中显式地引发异常。
-
自定义异常:
- 程序员可以根据需要创建自定义异常类,继承自 Exception 或其子类,以表示特定的异常情况。
-
finally 块:
- finally 块中的代码无论是否发生异常都会执行。通常用于释放资源,确保资源在异常发生时得到释放
-
-
-
简述 throw 和 throws 关键字的区别
-
throw 关键字:
- 作用: throw 用于在代码中手动抛出一个异常对象。通常用于在程序执行过程中遇到错误或特定条件时,显式地抛出异常,中断程序的正常执行流程。
- 用法: throw 后面跟随一个异常对象,该对象可以是已有的异常类的实例,也可以是自定义异常类的实例。
- throw new CustomException("This is a custom exception");
-
throws 关键字:
- 作用: throws 用于在方法声明中指定可能抛出的异常类型。当一个方法可能抛出受检查异常(checked exception)时,需要在方法声明中使用 throws 关键字声明该异常,通知调用者可能需要处理这些异常。
- 用法: throws 后面跟随一个异常类型或多个异常类型,使用逗号分隔。
- throws 通常出现在方法的声明部分,而不是在方法体中。它是一种声明性的机制,用于提示调用者有可能需要处理的异常。
- 总结:
- throw 用于在代码中手动抛出异常对象。
- throws 用于在方法声明中指定可能抛出的异常类型。
-
-
简述静态方法与非静态方法的区别?
-
静态方法:
- 关键字: 静态方法使用 static 关键字修饰。
- 调用方式: 可以通过类名直接调用,无需实例化类。也可以通过实例化类的对象调用,但不推荐,因为它可能引起误导。
- 访问属性: 静态方法不能直接访问类的实例变量,只能访问类的静态变量。
- this 关键字: 静态方法中不能使用 this 关键字,因为它表示当前对象实例,而静态方法不属于任何特定的实例。
- 应用: 通常用于工具类、辅助类,或者不依赖对象状态的方法。
-
非静态方法:
- 关键字: 非静态方法没有使用 static 关键字修饰。
- 调用方式: 必须通过实例化类的对象来调用,因为非静态方法依赖于对象的状态。
- 访问属性: 可以直接访问类的实例变量和静态变量。
- this 关键字: 可以使用 this 关键字引用当前对象实例,表示调用该方法的对象。
- 应用: 通常用于表达对象的行为,依赖于对象的状态。
- 总的来说,静态方法属于类,与特定的实例无关,而非静态方法属于对象实例,依赖于对象的状态。选择使用静态方法还是非静态方法取决于方法的功能和是否依赖于对象的状态。
-
-
什么是构造方法?构造方法有哪些特点?
- 构造方法(Constructor)是一种特殊类型的方法,用于在创建对象时进行初始化操作。它的名称必须与类名相同,没有返回类型(包括 void),在使用 new 关键字创建对象时自动调用。构造方法通常用于初始化对象的实例变量或执行其他必要的初始化操作。
- 构造方法的特点包括:
- 与类同名: 构造方法的名称必须与其所属类的名称完全相同。
- 没有返回类型: 构造方法没有返回类型,包括 void,因为其主要目的是初始化对象,而不是返回值。
- 在对象创建时自动调用: 构造方法在使用 new 关键字创建对象时自动调用。每次创建对象时,都会执行相应的构造方法。
- 可以重载: 与普通方法一样,构造方法可以被重载,即在同一个类中可以定义多个构造方法,它们的参数列表不同。
- 可以包含初始化代码: 构造方法中可以包含一些初始化代码,用于初始化对象的实例变量或执行其他初始化操作。
- 默认构造方法: 如果类没有显式定义构造方法,Java 会提供一个默认的无参构造方法。如果类定义了任何构造方法,但没有提供无参构造方法,则默认构造方法不再提供。
-
什么叫类中类?主要包括哪几种类中类?请简述其特点和作用
- 在Java中,类中类主要指的是嵌套类(Nested Class),也被称为内部类(Inner Class)。嵌套类是定义在其他类内部的类,Java支持多种嵌套类,包括静态嵌套类、成员内部类、局部内部类和匿名内部类。
-
静态嵌套类(Static Nested Class):
- 特点: 静态嵌套类是一个静态的类,它位于另一个类的内部,但与外部类的实例无关。
- 作用: 可以用于组织相关的类,并且不依赖于外部类的实例
-
成员内部类(Member Inner Class):
- 特点: 成员内部类是一个非静态的类,它依赖于外部类的实例。
- 作用: 可以访问外部类的实例变量和方法,并与外部类实例关联。
-
局部内部类(Local Inner Class):
- 特点: 局部内部类是定义在方法内部的类,它只在定义它的方法中可见。
- 作用: 通常用于解决某个方法中的特定问题,具有较小的作用域。
-
匿名内部类(Anonymous Inner Class):
- 特点: 匿名内部类是一种没有显示定义类名的内部类,通常用于创建接口实例或继承父类。
- 作用: 简化代码,通常用于创建临时的、一次性的类。
- 特点和作用总结:
- 静态嵌套类独立于外部类的实例,常用于组织相关的类。
- 成员内部类依赖于外部类的实例,可以访问外部类的实例变量和方法。
- 局部内部类只在定义它的方法中可见,常用于解决某个方法中的特定问题。
- 匿名内部类通常用于创建临时的、一次性的类实例,简化代码。
-
简述静态代码块/构造代码块/同步代码块/普通代码块的特点
-
静态代码块(Static Initialization Block):
- 位置: 静态代码块位于类中,使用 static 关键字修饰,会在类加载时执行,仅执行一次。
- 作用: 通常用于进行类的初始化操作,如加载驱动、初始化静态变量等。
-
构造代码块(Instance Initialization Block):
- 位置: 构造代码块位于类中,没有使用 static 关键字修饰,会在每次创建对象时执行。
- 作用: 用于对象的初始化操作,每次创建对象都会执行构造代码块。
-
同步代码块(Synchronized Block):
- 位置: 同步代码块是一种使用 synchronized 关键字定义的代码块,用于实现多线程同步。
- 作用: 通过锁机制确保多线程访问共享资源时的互斥性,避免竞态条件。
-
普通代码块:
- 位置: 普通代码块是定义在方法、循环、条件语句等中的一段局部代码。
- 作用: 提供了局部作用域,用于限制变量的生命周期,防止变量过早进入垃圾回收。
- 特点总结:
- 静态代码块在类加载时执行,用于进行类的初始化操作。
- 构造代码块在每次创建对象时执行,用于对象的初始化操作。
- 同步代码块用于实现多线程同步,通过锁机制确保互斥性。
- 普通代码块提供局部作用域,用于限制变量的生命周期。
-
-
简述实现字节流/字符流的读写过程
-
字节流的读写过程:
- 字节输出流(OutputStream)的写入过程:
- 创建流对象: 创建一个字节输出流对象,通常使用文件输出流或其他输出流的子类。
- 写入数据: 使用 write() 方法写入字节数据到输出流中。
- 刷新和关闭: 调用 flush() 方法刷新输出流,确保数据被写入目标,然后关闭输出流。
- 字节输入流(InputStream)的读取过程:
- 创建流对象: 创建一个字节输入流对象,通常使用文件输入流或其他输入流的子类。
- 读取数据: 使用 read() 方法从输入流中读取字节数据。
- 关闭流: 读取完成后关闭输入流
- 字符流的读写过程:
- 字符输出流(Writer)的写入过程:
- 创建流对象: 创建一个字符输出流对象,通常使用文件写入流或其他输出流的子类。
- 写入数据: 使用 write() 方法写入字符数据到输出流中。
- 刷新和关闭: 调用 flush() 方法刷新输出流,确保数据被写入目标,然后关闭输出流。
- 字符输入流(Reader)的读取过程:
- 创建流对象: 创建一个字符输入流对象,通常使用文件读取流或其他输入流的子类。
- 读取数据: 使用 read() 方法从输入流中读取字符数据。
- 关闭流: 读取完成后关闭输入流。
- 字符输出流(Writer)的写入过程:
- 总体而言,字节流适用于处理二进制数据,而字符流适用于处理文本数据。字符流在处理文本数据时能更好地处理字符编码和换行符等特殊情况。
- 字节输出流(OutputStream)的写入过程:
-
-
什么叫向上转型/向下转型?
-
向上转型(Upcasting):
- 定义: 向上转型是指将一个子类类型的对象引用赋值给一个父类类型的引用变量。
- 发生时机: 当一个子类对象的引用被赋值给一个父类引用时,就发生了向上转型。
- 特点: 向上转型是自动进行的,不需要显式的类型转换。被转型后的对象只能访问父类中定义的属性和方法,而不能访问子类新增的属性和方法。
-
向下转型(Downcasting):
- 定义: 向下转型是指将一个父类类型的对象引用转换为其子类类型的引用。
- 发生时机: 当一个父类类型的引用指向一个子类对象,并且我们希望调用子类特有的方法或访问子类特有的属性时,需要进行向下转型。
- 特点: 向下转型需要显式的类型转换,否则编译器会报错。在进行向下转型之前,通常需要使用 instanceof 运算符检查对象的类型,以避免转型异常
- 总体而言,向上转型是安全的,而向下转型需要谨慎,应该在确保安全的情况下进行。使用 instanceof 运算符可以在向下转型之前进行类型检查,以避免潜在的运行时异常。
-
-
什么叫泛型?
- 泛型(Generics)是Java语言中引入的一项特性,用于提供编译时类型安全性和程序的可重用性。泛型允许在类、接口、方法的定义中使用类型参数,使得类或方法能够操作不同类型的数据而不失去类型安全性
- 泛型类(Generic Class): 允许在类的定义中使用类型参数,使得类可以处理不同类型的数据。
- 泛型接口(Generic Interface): 允许在接口的定义中使用类型参数,使得接口能够操作不同类型的数据。
- 泛型方法(Generic Method): 允许在方法的定义中使用类型参数,使得方法能够在调用时接收不同类型的参数。
- 通配符(Wildcard): 使用 ? 表示未知类型,可以用在泛型方法的参数、泛型类的实例化等场景。
- 泛型的主要优势包括:
- 类型安全性: 泛型提供了编译时的类型检查,可以在编译阶段捕获类型错误,避免在运行时发生类型异常。
- 代码重用性: 泛型代码可以在不同类型之间实现高度的代码重用,减少了重复编写相似代码的需求。
- 程序清晰度: 泛型提高了程序的可读性和可维护性,使得代码更加清晰和直观。
- 泛型(Generics)是Java语言中引入的一项特性,用于提供编译时类型安全性和程序的可重用性。泛型允许在类、接口、方法的定义中使用类型参数,使得类或方法能够操作不同类型的数据而不失去类型安全性
- 资料为收集得到,主要是为了分享相关知识点,希望对你有帮助。