当前位置:   article > 正文

Java基础面试题&知识点总结(上篇)_java试题 知识点

java试题 知识点

大家好,我是栗筝i,从 2022 年 10 月份开始,我便开始致力于对 Java 技术栈进行全面而细致的梳理。这一过程,不仅是对我个人学习历程的回顾和总结,更是希望能够为各位提供一份参考。因此得到了很多读者的正面反馈。

而在 2023 年 10 月份开始,我将推出 Java 面试题/知识点系列内容,期望对大家有所助益,让我们一起提升。

今天与您分享的,是 Java 基础知识面试题系列的总结篇(上篇),我诚挚地希望它能为您带来启发,并在您的职业生涯中起到助益作用。衷心感谢每一位朋友的关注与支持。



1、Java基础面试题问题
1.1、语言和语法
1.2、面向对象

2、Java基础面试题解答
2.1、语言和语法
  • 问题 01. 介绍一下你了解的 Java,它的主要特性有哪些?

解答:

Java 是一种高级、面向对象的编程语言,由 Sun Microsystems(现在的 Oracle Corporation)在 1995 年发布。它最初被设计用于小型、网络环境下的应用程序开发,但随着时间的推移,Java 发展成为了一个功能强大的全面编程语言,广泛应用于开发桌面、网站、服务端应用、移动应用和嵌入式系统。

以下是 Java 的一些核心特性:

  1. 简单性:Java 设计时力求简洁易用,去除了 C++ 中容易引起错误的功能,如指针和运算符重载。
  2. 面向对象:Java 是一种纯粹的面向对象语言。除了基本数据类型外,所有的元素都是对象。
  3. 跨平台能力:Java 程序是先编译为平台无关的字节码,然后可以在任何安装了 Java 虚拟机(JVM)的平台上运行。这个特性使得 Java 应用程序具有高度的移植性。
  4. 安全性:Java 提供了一个安全管理器,用于定义类加载和内存访问等的访问权限。这样可以防止不信任的代码对系统进行潜在的有害操作。
  5. 健壮性:强类型检查机制、异常处理和垃圾回收等特性都使得 Java 程序更加健壮。
  6. 多线程:Java 内置了对多线程编程的支持,允许你创建交互式的应用程序和提高性能。
  7. 大规模的标准库:Java 提供了一套庞大的标准库(Java API),涵盖了从基本数据结构到网络编程的各个方面。
  8. 高性能:Java 的性能随着时间的推进已经得到了显著提高,尤其是 JIT 编译器的引入,使得 Java 程序运行速度大大加快。
  9. 动态性:Java 能够适应不断发展的环境。新的 Java 代码可以轻松地与应用程序集成,不需要创建一个完全独立的新版本。

总之,Java 以其强大的功能、稳定的跨平台性能和广泛的应用领域,成为了当今世界上最流行的编程语言之一。

  • 问题 02. 什么是 Java 平台?

解答:

Java 平台是一个广泛的技术框架,它提供了开发和运行 Java 编程语言应用程序的环境。Java 平台不仅包括编程语言本身,还包括一系列的执行环境、API 和相关的技术标准。这个平台的核心组件可以分为以下几个部分:

  1. Java 语言:Java 语言是一种面向对象、类似 C++ 的编程语言,但设计上更简洁、更安全。

  2. Java 虚拟机(JVM):JVM 是一个抽象的计算机,它运行编译后的 Java 程序字节码,并且能够在不同的硬件和操作系统平台之间提供一致的运行环境。这就是 Java 平台实现“一次编写,到处运行”(Write Once, Run Anywhere)特性的关键。

  3. Java API:Java 提供了一组丰富的标准类库(API),覆盖从基本数据结构到网络通信的各个方面。

  4. Java 开发工具包(JDK):JDK 包括 JVM、编译器、调试器以及其他工具,这些工具被用于开发 Java 应用程序。

Java 平台通常可以分为以下几个不同的版本,以满足不同类型的设备和应用需求:

  1. Java Standard Edition (Java SE):这是最常用的 Java 平台版本,用于开发和部署桌面、服务器和嵌入式应用程序。它包括 JVM 标准实现和核心 API 库。

  2. Java Enterprise Edition (Java EE):在 Java SE 的基础上,Java EE 添加了支持企业级应用程序的 API,这些 API 包括网络服务、Web 服务和事务管理等。

  3. Java Micro Edition (Java ME):Java ME 针对嵌入式和移动设备提供了一个优化的运行时环境,支持更小的内存和处理能力。

  4. JavaFX:用于创建丰富的客户端用户界面的库和工具,现在通常被包括在 Java SE 中。

Java 平台的这些组件协同工作,提供了一个完整、稳定、跨平台的开发环境,使得 Java 成为了开发各种应用程序的流行选择。

  • 问题 03. Java 中的基本数据类型有哪些?

解答:

在 Java 中,基本数据类型(也称为原始数据类型)是最基础的数据类型,它们不是对象,也不属于任何类。这些类型代表了简单的数值和字符。Java 定义了八种基本数据类型,分为四类:

  1. 整型:byte:占用 1 字节,范围从 -128 到 127。short:占用 2 字节,范围从 -32,768 到 32,767。int:占用 4 字节,范围从 -231 到 231-1。在 Java 中,int 是默认的整数类型。long:占用 8 字节,范围从 -263 到 263-1。

  2. 浮点型:float:占用 4 字节,范围覆盖大约 ±3.40282347E+38F(有效位数为 6~7 位十进制数)。double:占用 8 字节,范围覆盖大约 ±1.79769313486231570E+308(有效位数为 15 位十进制数)。

  3. 字符型:char:占用 2 字节,用于表示单个 Unicode 字符,范围从 ‘\u0000’(即为 0)到 ‘\uffff’(即为 65,535)。

  4. 布尔型:boolean:Java 语言规范中没有明确指定 boolean 类型的大小,但是它只有两个可能的值:truefalse

每种基本数据类型都有其对应的包装类,使得可以将这些基本类型当作对象来处理。例如,int 类型的包装类是 Integerdouble 类型的包装类是 Double,依此类推。包装类提供了一些有用的方法和属性,也允许基本数据类型在需要对象的地方使用,如在集合类中。

  • 问题 04. Java 中的自动装箱和拆箱是什么?

解答:

在 Java 中,自动装箱(Autoboxing)和拆箱(Unboxing)是自 Java 5 开始引入的特性,它们允许基本数据类型和它们对应的对象包装类型之间自动转换。

自动装箱 是指将基本数据类型自动转换为对应的包装类对象的过程。例如,当你将一个 int 类型的值赋给一个 Integer 类的对象时,Java 编译器会自动将 int 值转换为 Integer 对象。这样做的好处是简化了代码,使得开发者不需要显式地进行转换。

Integer iObj = 10; // 自动装箱,编译器会转换为 Integer iObj = Integer.valueOf(10);
  • 1

拆箱 是指将包装类对象转换回基本数据类型的过程。例如,当你从一个 Integer 类的对象中取出基本 int 类型的值时,Java 编译器会自动进行转换。

int i = iObj; // 自动拆箱,编译器会转换为 int i = iObj.intValue();
  • 1

这两个过程大大简化了编程,因为在很多情况下,你不需要显式地进行对象的包装和拆包。然而,需要注意的是,在某些情况下,自动装箱和拆箱可能会引入不必要的对象创建,从而影响性能。此外,拆箱操作可能会抛出 NullPointerException,如果尝试拆箱的包装对象是 null 的话。

例如,下面这段代码就会引发异常:

Integer nullInteger = null;
int i = nullInteger; // 会抛出 NullPointerException
  • 1
  • 2

因此,虽然自动装箱和拆箱提供了便利,开发者还是需要留意潜在的性能问题和空指针异常的风险。

  • 问题 05. Java 中的自动类型转换和强制类型转换

解答:

在 Java 中,类型转换主要有两种形式:自动类型转换(也称为隐式转换)和强制类型转换(显式转换)。

自动类型转换:当两种不同的数据类型进行运算时,如果数据类型大小不一致,那么较小的数据类型会自动转换为较大的数据类型,这个过程叫做自动类型转换。自动类型转换遵循一定的规则,通常发生在有明确转换规则且不会导致信息损失的场景中。例如,int 可以自动转换为 longfloat 可以自动转换为 double。示例:

int i = 100;
long l = i; // 自动类型转换,int 转换为 long
float f = l; // 自动类型转换,long 转换为 float
  • 1
  • 2
  • 3

强制类型转换:当需要将一个数据类型强制转换为另一个较小的数据类型时,需要使用强制类型转换。这是显式的转换,可能会导致信息丢失或精度降低。强制类型转换需要在值前加上希望转换到的类型。示例:

double d = 100.04;
long l = (long) d; // 强制类型转换,double 转换为 long,可能丢失小数部分
int i = (int) l; // 强制类型转换,long 转换为 int
  • 1
  • 2
  • 3

在使用强制类型转换时,开发者需要意识到可能存在的数据丢失风险,并在必要时进行相应的处理。

  • 问题 06. Java 的编译和执行过程

解答:

Java 的编译和执行过程涉及几个关键步骤,具体如下:

  1. 编写源代码:开发者使用文本编辑器或集成开发环境(IDE)编写以 .java 为扩展名的源代码文件。

  2. 编译源代码:使用 Java 编译器 javac.java 文件编译成 Java 字节码(.class 文件)。字节码是一种中间代码,它不同于机器码,是一种平台无关的代码。

    javac FileName.java
    
    • 1
  3. 加载字节码:当运行程序时,Java 虚拟机(JVM)的类加载器负责将 .class 文件加载到内存中。

  4. 字节码验证:加载到 JVM 的字节码会经过验证器检查,确保字节码安全并符合 Java 语言规范,防止运行时出现安全风险。

  5. 执行字节码:经过验证的字节码被送到执行引擎。JVM 中的执行引擎可以采用解释执行(逐条解释字节码),也可以通过即时编译器(JIT)将字节码编译成本地机器码提高效率。

    java FileName
    
    • 1
  6. 运行时处理:在程序执行过程中,JVM 会进行内存管理、垃圾回收以及其他与运行时环境相关的操作。

整个过程中,JVM 的作用至关重要,它不仅能够执行字节码,还提供了与操作系统无关的运行环境,使 Java 程序具有跨平台性,即"一次编写,到处运行"(Write Once, Run Anywhere)。

要注意的是,这个过程可能稍有不同,比如当使用即时编译(JIT)的时候,执行过程会涉及把字节码转换为机器码,这通常在程序运行时动态进行。还有一些情况下,可以将字节码预先编译成本地代码来提高性能,这通常是通过 Java 的 Ahead-Of-Time (AOT) 编译器来实现的。

  • 问题 07. Java 中的包(package)及其用途

解答:

在 Java 中,包(package)是用来组织类和接口的一种机制。使用包可以将功能相似或相关的类和接口组织在一起,这样做不仅有助于代码的模块化,还能避免类名冲突。包在物理上对应于文件系统的目录。用途:

  1. 命名空间管理:包为类和接口提供了命名空间,可以防止命名冲突。不同包中可以有同名的类或接口。

  2. 访问控制:包可以用来控制类和接口的访问权限。Java 有一种默认的访问级别(默认访问级别),如果类或类成员没有明确的访问级别指定,它们只能被同一包内的类访问。

  3. 可重用性:包可以包含多个类和接口,可以被不同的程序和模块重用。

  4. 易于维护:包提供了一种将代码逻辑上组织为独立模块的方式,这使得代码更易于理解和维护。

声明包:在 Java 源文件中,通过在文件顶部使用 package 关键字来声明包。例如:

package com.example.myapp;
  • 1

这行代码声明了一个包名为 com.example.myapp 的包。这个包可以包含多个类和接口。

使用包中的类:如果要在某个类中使用其他包中的类或接口,需要使用 import 关键字导入相应的包。例如:

import com.example.myapp.SomeClass;
  • 1

这行代码导入了 com.example.myapp 包中的 SomeClass 类。

如果导入同一包中的所有类和接口,可以使用星号(*)作为通配符:

import com.example.myapp.*;
  • 1

包结构通常反映了企业的域名,反向写出,以确保全球唯一性,从而避免命名冲突。例如,一个名为 MyApp 的应用,由 example.com 域的企业开发,可能会有一个基础包名 com.example.myapp

2.2、面向对象
  • 问题 08. 如何在 Java 中定义一个类?

解答:

在 Java 中,一个类是定义对象属性和行为的蓝图或原型。定义一个类涉及声明类的名称、属性(也称为字段或成员变量)和方法。以下是一个简单的 Java 类的定义示例:

public class Car {
    
    // 成员变量(属性)
    private String color;
    private String brand;
    private int year;

    // 构造器
    public Car(String color, String brand, int year) {
        this.color = color;
        this.brand = brand;
        this.year = year;
    }

    // 方法
    public void startEngine() {
        System.out.println("引擎启动了!");
    }

    // 更多的方法和逻辑可以在这里定义...

    // Getter 和 Setter 方法
    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    // 对于 brand 和 year 同样可以定义 Getter 和 Setter 方法
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

这个类有以下组成部分:

  1. 类声明:public class Car { ... }public 是一个访问修饰符,表示这个类是公开的,可以被其他类访问。Car 是类名,Java 中类名通常采用大驼峰命名规则。

  2. 成员变量:color, brand, 和 year 是类的属性,定义了汽车的几个基本特征。这些变量被声明为 private,这意味着它们仅在类内部访问,以保证封装性。

  3. 构造器:构造器是一种特殊的方法,名称与类名相同。它在创建类的实例时被调用,用于初始化对象。

  4. 方法:startEngine 是一个定义类行为的方法。你可以定义更多的方法来提供类的功能。

  5. Getter 和 Setter 方法:提供了获取(get)和设置(set)成员变量值的方法。这些方法是公共的(public),允许从类的外部访问和修改私有变量的值,同时仍然保持封装性。

通过定义类,你可以创建具有特定状态和行为的对象。在 Java 中创建 Car 类的实例,你可以这样做:

Car myCar = new Car("红色", "丰田", 2020);
myCar.startEngine();
  • 1
  • 2

以上代码创建了一个 Car 对象,并调用了其 startEngine 方法。

  • 问题 09. 如何在 Java 中创建一个对象?

解答:

在 Java 中,创建对象的过程通常涉及以下两个步骤:

  1. 声明:声明一个变量来存储对象引用。
  2. 实例化:使用 new 关键字来创建一个类的实例。

这里是一个创建对象的示例,假设我们有一个 Car 类:

// 假设已经定义了一个Car类
public class Car {
    private String color;

    // 构造器
    public Car(String carColor) {
        // 初始化颜色属性
        color = carColor;
    }

    // 定义其他方法和逻辑
}

// 在另一个类中或者同一个类的方法中创建Car对象
public class Main {
    public static void main(String[] args) {
        // 声明并实例化Car类的对象
        Car myCar = new Car("Blue");
        
        // 使用myCar对象的引用来调用方法或访问其属性等...
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

在这个例子中:

  1. Car myCar 声明了一个类型为 Car 的变量 myCar,这个变量用来引用 Car 类型的对象。
  2. new Car("Blue") 通过调用 Car 类的构造器 Car(String carColor) 来创建一个新的 Car 对象实例,并将其内存地址赋值给 myCar 变量。此时,对象的 color 属性被初始化为字符串 "Blue"
  3. 通过 myCar 变量,你可以调用 Car 对象的任何公共方法和变量。

实际使用中,你可能需要根据类的构造器传入相应的参数来创建对象,上述示例中传入的 "Blue" 就是在创建 Car 对象时设置的颜色属性。

  • 问题 10. 什么是面向对象编程?

解答:

面向对象编程(Object-Oriented Programming,简称 OOP)是一种编程范式,它使用 “对象” 来设计软件和创建可重用的代码。

在 OOP 中,每个对象都是一个特定类的实例。类定义了对象的属性(也称为数据成员或字段)和方法(也称为成员函数或行为)。对象的属性是用来存储数据的,而方法则是用来执行任务的。

OOP 主要有以下四个基本特性:

  1. 封装:封装是将对象的状态(属性)和行为(方法)包装在一起的过程。封装可以隐藏对象的内部实现细节,只暴露出需要的信息。

  2. 继承:继承是从已有的类派生出新的类的过程。新的类(子类)可以继承父类的属性和方法,并可以添加新的属性和方法,也可以重写父类的方法。

  3. 多态:多态是指允许一个接口使用多种实际类型的能力。多态可以使得代码更加灵活和可扩展。

  4. 抽象:抽象是将复杂的系统简化的过程。我们可以通过创建抽象类或接口来定义对象的通用结构。

面向对象编程的主要目标是提高软件的可重用性、灵活性和可维护性。

  • 问题 11. 什么是封装?Java 中如何实现?

解答:

封装是面向对象编程(OOP)的一个核心概念,它指的是将对象的状态(属性)和行为(方法)组合到一个高度组织的对象中,并对对象的内部实现进行隐藏,仅对外公开一个清晰定义的接口。

封装的主要优点包括:

  • 增强安全性:限制对某些组件的访问,防止外部代码随意更改内部状态。
  • 简化接口:隐藏内部复杂性,只需通过对象提供的方法即可与对象交互。
  • 易于维护:通过减少系统各部分之间的相互依赖,使得代码更容易被更新或修改。

在 Java 中,封装可以通过以下方式实现:

  • 通过访问修饰符控制访问级别:使用 private, protected, public 等访问修饰符来定义类成员的可见性。通常,属性被设置为 private,这意味着它们只能被类的方法访问和修改,而不是直接从类外部访问。

  • 提供公共的 getter 和 setter 方法:如果需要从类外部读取或修改私有属性,则可以通过定义公共的 getter 方法来访问属性值,以及通过 setter 方法来修改属性值。这些方法提供了对属性的受控访问,你可以在这些方法内部添加逻辑,例如验证数据,或者在属性值变化时执行某些操作。

下面是一个简单的 Java 类来演示封装:

public class Person {
    private String name; // 私有属性,外部无法直接访问
    private int age;     // 私有属性,外部无法直接访问

    // 构造器
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // name 的 getter 方法
    public String getName() {
        return name;
    }

    // name 的 setter 方法
    public void setName(String name) {
        this.name = name;
    }

    // age 的 getter 方法
    public int getAge() {
        return age;
    }

    // age 的 setter 方法
    public void setAge(int age) {
        if (age > 0) {
            this.age = age;
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

在这个 Person 类中,nameage 属性是私有的,外部代码不能直接访问它们。但是,通过公共的 getter 和 setter 方法,外部代码可以在对象授权的情况下读取和修改这些属性的值。这种方式加强了属性的安全性,并提供了灵活的属性管理机制。

  • 问题 12. 什么是继承?Java 支持多重继承吗?

解答:

继承是面向对象编程(OOP)的另一个基本概念,允许一个类(称为子类或派生类)继承另一个类(称为父类或基类)的属性和方法。继承提供了以下几个主要优点:

  • 代码重用:子类可以复用父类中的代码,不需要重复编写相同的代码。
  • 建立类之间的关系:继承可以表达出类之间的层次关系,提高了类的组织结构。
  • 多态性:允许使用父类类型的引用来指向子类对象,从而实现多态,在运行时决定具体调用哪个类的方法。

在 Java 中,继承是通过使用 extends 关键字来实现的。例如:

public class Vehicle {
    // 父类的属性和方法
}

public class Car extends Vehicle {
    // Car 类继承了 Vehicle 类的属性和方法
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

这里,Car 类就继承了 Vehicle 类的所有公有(public)和保护(protected)成员。私有成员(private)虽然也被继承,但是不可直接访问,只能通过父类提供的公有或保护方法来访问。

关于多重继承:Java 不支持通过类的方式进行多重继承,即一个类不能有多个直接父类。这是因为多重继承可能会导致复杂性显著增加,特别是当多个父类有相同的方法时,子类可能不明确应该继承哪个父类的方法。

为了解决这个问题,Java 提供了接口(Interface)的概念。一个类可以实现(implements)多个接口,并且必须实现接口中所有的抽象方法。接口允许 Java 以不同的方式实现多继承的部分特征。

public interface Flyable {
    void fly();
}

public interface Floatable {
    void floatOnWater();
}

public class Seaplane extends Vehicle implements Flyable, Floatable {
    public void fly() {
        // 实现飞行的代码
    }

    public void floatOnWater() {
        // 实现在水面漂浮的代码
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

在这个例子中,Seaplane 类继承自 Vehicle 类,并且实现了 FlyableFloatable 两个接口,从而在单继承的限制下实现了多继承的效果。

  • 问题 13. 什么是多态?Java 如何实现多态?

解答:

多态是面向对象编程中的一个基本概念,指的是同一个行为具有多个不同表现形式或状态。在 Java 中,多态表现为以下两种形式:

  1. 编译时多态(或静态多态):这种多态是通过方法重载(Overloading)实现的。重载发生在同一个类中,当有多个方法名相同但参数列表不同时,编译器根据方法签名在编译期就决定了会调用哪个方法。这种多态是在编译时确定的,因此称为静态多态。

    class Demo {
        void display(int a) {
            System.out.println("Integer: " + a);
        }
        
        void display(int a, int b) {
            System.out.println("Two Integers: " + a + " and " + b);
        }
        
        void display(String a) {
            System.out.println("String: " + a);
        }
    }
    // 使用
    Demo d = new Demo();
    d.display(1);          // 调用第一个方法
    d.display(1, 2);       // 调用第二个方法
    d.display("Hello");    // 调用第三个方法
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
  2. 运行时多态(或动态多态):这种多态是通过方法重写(Overriding)实现的。当子类提供与父类具有相同名称和参数列表的方法时,子类的方法会覆盖父类的方法。运行时,根据对象的实际类型来决定调用哪个方法,这就需要动态绑定。

    class Animal {
        void sound() {
            System.out.println("Animal makes a sound");
        }
    }
    
    class Dog extends Animal {
        @Override
        void sound() {
            System.out.println("Dog barks");
        }
    }
    
    // 使用
    Animal animal = new Dog();
    animal.sound();  // 输出 "Dog barks" 而不是 "Animal makes a sound"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在这个例子中,尽管 animal 的编译类型是 Animal,但它的运行时类型是 Dog,因此调用的是 Dog 类中重写的 sound 方法。

在 Java 中,所有的类都是继承自 java.lang.Object。因为多态的存在,任何时候我们都可以将子类的实例赋值给父类类型的变量,这种向上转型(Upcasting)是自动的。向下转型(Downcasting)则需要显式地进行类型转换,但它是不安全的,因为它要求我们必须确保实例确实属于目标类型。

多态的存在让 Java 程序设计更加灵活和可扩展,我们可以通过抽象类和接口来设计方法和类,这样就可以在不同的实现之间切换,而不用修改大量代码。

  • 问题 14. 什么是访问修饰符?

解答:

访问修饰符(Access Modifiers)在 Java 中定义了类、变量、方法和构造器的访问控制。它们决定了一个成员(例如字段或方法)的可访问性。Java 提供了四种访问级别:

  1. private - 私有的访问级别,被标记为 private 的成员只能在声明它的类中被访问。

    public class ClassA {
        private int privateVariable = 5;
    }
    
    • 1
    • 2
    • 3
  2. default (又称为 package-private) - 如果没有指定访问修饰符,则默认使用 default 访问级别。这样的成员只能在同一个包内的类中被访问。

    class ClassB {
        int defaultVariable = 10;
    }
    
    • 1
    • 2
    • 3
  3. protected - 被 protected 修饰的成员可以被同一个包内的类以及其他包中的子类访问。

    public class ClassC {
        protected int protectedVariable = 15;
    }
    
    • 1
    • 2
    • 3
  4. public - 公共的访问级别,被 public 修饰的成员可以在任何地方被访问。

    public class ClassD {
        public int publicVariable = 20;
    }
    
    • 1
    • 2
    • 3

每个级别都提供了不同的访问控制,使得程序员可以在封装和继承中做出合适的选择,以便保护数据并提供接口。在设计 Java 类时,合理使用这些访问修饰符是面向对象设计原则的一个重要方面。

  • 问题 15. 什么是 this 关键字?什么是 super 关键字?

解答:

在 Java 中,thissuper 关键字用于引用对象的当前实例和当前实例的父类上下文。

this 关键字,this 关键字在 Java 中用于:

  1. 引用当前对象的成员变量。
  2. 在构造函数中调用另一个重载的构造函数。
  3. 将当前对象传递给方法或构造器。
  4. 在内部类中引用外部类的实例。

以下是 this 关键字用法的例子:

public class MyClass {
    int variable;

    MyClass(int variable) {
        // 引用当前实例的成员变量
        this.variable = variable;
    }

    void myMethod() {
        // 将当前对象作为参数传递
        someMethod(this);
    }

    void someMethod(MyClass instance) {
        // 处理 instance
    }
    
    MyClass() {
        // 调用另一个构造函数
        this(0);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

super 关键字,super 关键字在 Java 中用于:

  1. 引用父类的成员变量。
  2. 调用父类的方法。
  3. 在子类构造器中调用父类的构造器。

以下是 super 关键字用法的例子:

class ParentClass {
    int variable = 5;
}

class ChildClass extends ParentClass {
    int variable = 10;

    void show() {
        // 访问当前类的成员变量
        System.out.println(variable);
        // 访问父类的成员变量
        System.out.println(super.variable);
    }

    ChildClass() {
        // 调用父类的构造器
        super();
    }

    @Override
    void parentMethod() {
        // 调用父类的方法
        super.parentMethod();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

在执行子类与父类有相同成员时,super 可以明确指出是调用父类的成员。在构造子类的实例时,如果想调用父类的构造函数(无论是默认的还是带参数的),可以使用 super() 来实现。通常,如果子类的构造器没有显式调用 super(),编译器会插入一个无参的 super() 调用。

  • 问题 16. 解释方法重载和重写的区别。

解答:

方法重载和方法重写是 Java 中两种重要的特性。

  1. 方法重载(Overloading):在同一个类中,如果有多个方法的名称相同,但参数列表不同(参数的数量、类型或顺序不同),那么这些方法就被称为重载方法。方法重载允许我们使用同一个方法名执行不同的操作。

  2. 方法重写(Overriding):在子类中,如果有一个方法与父类的某个方法的名称、参数列表和返回类型都相同,那么这个方法就被称为重写方法。方法重写允许我们在子类中改变父类的行为。

方法重载和方法重写的主要区别如下:

  1. 应用场景:方法重载发生在同一个类中,方法重写发生在父类和子类之间。
  2. 参数列表:方法重载要求参数列表不同,方法重写要求参数列表相同。
  3. 返回类型:方法重载对返回类型没有特殊要求,方法重写要求返回类型相同或是父类方法返回类型的子类型。
  4. 访问修饰符:方法重载对访问修饰符没有特殊要求,方法重写要求子类方法的访问级别不能低于父类方法的访问级别。

总的来说,方法重载是静态的,它在编译时就已经确定了具体调用哪个方法;而方法重写是动态的,它在运行时才确定具体调用哪个方法。

  • 问题 17. 什么是接口和抽象类?他们有什么区别?

解答:

接口(Interface)和抽象类(Abstract Class)都是面向对象编程中的高级特性,它们都不能直接实例化,需要通过子类或实现类来实例化。

  1. 接口:接口是一种完全抽象的类,它只包含抽象方法(在 Java 8 之后,接口也可以包含默认方法和静态方法)。一个类可以实现多个接口,实现接口的类必须实现接口中的所有方法。

  2. 抽象类:抽象类是一种特殊的类,它可以包含抽象方法和非抽象方法。抽象方法是没有实现的方法,需要子类来提供实现。一个类只能继承一个抽象类。

接口和抽象类的主要区别如下:

  1. 实现接口的类需要实现接口中的所有方法,而继承抽象类的子类只需要实现抽象类中的抽象方法。
  2. 一个类可以实现多个接口,但只能继承一个抽象类。
  3. 接口中的所有方法默认都是 public 的,而抽象类中的方法可以有不同的访问修饰符。

总的来说,接口更多地被用来定义行为(即方法),而抽象类既可以定义行为,也可以定义状态(即属性)。在设计类的层次结构时,我们通常会使用抽象类,而在定义一组相关的行为时,我们通常会使用接口。

  • 问题 18. 什么是构造函数?它如何工作?

解答:

构造函数是一种特殊的方法,用于初始化新创建的对象。在 Java 中,构造函数的名称必须与类名相同,并且没有返回类型。

构造函数与普通方法的主要区别如下:

  1. 名称:构造函数的名称必须与类名相同,而普通方法可以有任何有效的标识符作为名称。

  2. 返回类型:构造函数没有返回类型,而普通方法必须有返回类型。

  3. 调用方式:构造函数在创建对象时自动调用,无需手动调用。而普通方法需要手动调用。

  4. 用途:构造函数主要用于初始化对象的状态(即设置属性的初始值)。而普通方法用于描述对象的行为。

例如,以下是一个简单的类,其中包含一个构造函数和一个普通方法:

public class MyClass {
    private int value;

    // 构造函数
    public MyClass(int value) {
        this.value = value;
    }

    // 普通方法
    public void displayValue() {
        System.out.println("Value: " + value);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

在这个例子中,MyClass 的构造函数接受一个参数 value,并将其赋值给对象的 value 属性。displayValue 是一个普通方法,用于打印对象的 value 属性。

  • 问题 19. 什么是 static 关键字?它有什么用途?

解答:

static 是 Java 中的一个关键字,它可以用来修饰类的成员(成员变量和成员方法),也可以用来创建静态代码块。

  1. 静态变量:static 关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有一份拷贝。 静态变量也被称为类变量。局部变量不能被声明为 static 变量。
  2. 静态方法:static 关键字用来声明独立于对象的静态方法。静态方法不能使用类的非静态变量。静态方法从参数列表得到数据,然后计算这些数据。
  3. 静态代码块:static 关键字还可以形成静态代码块以优化程序性能。static 代码块在类加载的时候就运行了,而且只运行一次,同时运行时机是在构造函数之前。

总的来说,static 关键字主要有以下几个作用:

  1. 实现类的成员共享,节省内存。
  2. 优化程序性能,提高运行效率。
  3. 作为工具类的方法修饰符,方便调用。
  • 问题 20. 什么是 final 关键字?它有什么用途?

解答:

在 Java 中,final 是一个关键字,它可以用来修饰类、方法和变量。

  1. final 类:如果一个类被声明为 final,那么它不能被继承。这意味着没有其他类可以是这个类的子类。final 类通常表示最终的、不可改变的实体,例如 String 类和 Integer 类都是 final 类。

  2. final 方法:如果一个方法被声明为 final,那么它不能被子类重写。但是,子类可以继承 final 方法。

  3. final 变量:如果一个变量被声明为 final,那么它的值就不能被修改,它就成为了一个常量。我们必须在声明 final 变量时或在构造函数中初始化它。

final 关键字提供了一种方式,可以明确表示某个实体不应该被改变。这对于创建不可变的对象和防止意外修改非常有用。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/661656
推荐阅读
相关标签
  

闽ICP备14008679号