赞
踩
1. JVM、JDK、JRE之间的关系
JDK(Java Development Kit),JRE(Java Runtime Environment)和JVM(Java Virtual Machine)是 Java 平台的三个关键组成部分,它们之间的关系如下:
JVM(Java虚拟机): JVM 是 Java 平台的核心组件之一。它是一个虚拟计算机,用于执行 Java 字节码(即编译后的 Java 代码)。JVM 负责将字节码翻译成底层操作系统和硬件可以理解的指令。它提供了内存管理、垃圾回收、线程管理等功能,以确保 Java 程序的跨平台性和可移植性。
JRE(Java运行时环境): JRE 是运行 Java 应用程序所需的最小环境。它包含了 JVM 以及 Java 标准类库(Java API)和其他运行时所需的文件。JRE 可以用于执行已经编译的 Java 应用程序,但无法进行 Java 开发或编译。如果只需运行 Java 应用程序而不进行开发,通常只需安装 JRE。
JDK(Java开发工具包): JDK 是用于 Java 开发的完整工具包。它包含了 JRE,以及开发人员所需的编译器(javac)和其他开发工具(如调试器、构建工具等)。JDK 提供了开发和调试 Java 应用程序所需的一切工具和资源。如果需要进行 Java 应用程序的开发,需要安装 JDK。
2. 单精度和双精度有什么区别?flaot num = 0.1对吗?
单精度(float)使用32位(4字节)内存来存储浮点数,而双精度(double)使用64位(8字节)内存来存储浮点数。由于双精度使用更多的内存空间,它可以表示比单精度更大范围的数值,并且具有更高的精度。具体来说,单精度可以表示大约7位有效数字的浮点数,而双精度可以表示大约15位有效数字的浮点数。
flaot num = 0.1不对,浮点数字面量默认被解释为双精度(double)类型,正确表示为
- flaot num = 0.1f
- // 或者
- float num = 0.1F
3. 属性和变量的区别?
属性(Property)和变量(Variable)是两个相关但不完全相同的概念。属性是面向对象编程中与类或对象关联的特征或状态,具有访问控制和特定的访问方式;变量是通用的数据存储位置,可以在程序中用于存储和操作数据。
4. 基础数据类型与引用数据类型
基础数据类型(Primitive Data Types)和引用数据类型(Reference Data Types)是两种不同的数据类型。
基础数据类型包括以下8种:
引用数据类型包括以下几种:
区别如下:
存储方式:
内存管理:
默认值:
传递方式:
方法调用:
5. 什么时候使用静态属性和静态方法?什么是静态代码块?
静态属性(Static Property)和静态方法(Static Method)是在类级别上定义的属性和方法,它们与类本身相关联,而不是与类的实例(对象)相关联。以下是关于何时使用静态属性和静态方法的一些建议:
静态属性的使用场景:
静态方法的使用场景:
需要注意的是,使用静态属性和静态方法应慎重,因为它们破坏了面向对象的封装性和可测试性。静态属性和静态方法的共享性和全局性可能导致代码的耦合度增加和可维护性降低。因此,应该在确保使用静态的合适性的同时,考虑其潜在的副作用,并根据具体情况进行权衡和设计。
静态代码块 static { } 中的代码会在类的信息加载完成后,自动调用。如调用类中的方法、new一个对象。
6. 构造函数是什么?
构造函数(Constructor)是一种特殊的方法,用于创建对象并初始化对象的成员变量。构造函数具有与类相同的名称,但没有返回类型,甚至没有void
关键字。构造函数在使用new
关键字创建对象时被自动调用,用于初始化对象的状态。
如果在类中没有显式定义构造函数,JVM会自动提供一个无参数的默认构造函数。但如果类中定义了至少一个构造函数,JVM将不会提供默认构造函数。
构造函数也可以使用访问修饰符来控制其可见性,例如public
、private
、protected
等,用于限制构造函数的访问权限。
- public class MyClass {
- public MyClass() {
- // 无参数构造函数
- }
-
- public MyClass(int value) {
- // 带一个参数的构造函数
- }
-
- public MyClass(String name, int age) {
- // 带多个参数的构造函数
- }
- }
7. 调用 new 关键字的过程发生了什么?
当使用new
关键字创建一个对象时,Java虚拟机(JVM)会按照以下步骤执行对象的创建过程:
分配内存:首先,JVM会在堆(Heap)内存中为对象分配内存空间。内存的分配是在运行时动态进行的。JVM会根据对象的大小来决定分配的内存空间。
初始化零值:在分配内存后,JVM会将分配的内存空间初始化为默认的零值,即将对象的所有成员变量初始化为其对应类型的默认值(例如,整数类型初始化为0,布尔类型初始化为false,引用类型初始化为null等)。
执行构造函数:接下来,JVM会根据对象的类型找到相应的构造函数,并执行构造函数中的代码。构造函数负责对对象进行进一步的初始化,可以设置成员变量的初始值,执行必要的操作等。
返回对象引用:在构造函数执行完成后,JVM会返回一个指向新创建对象的引用。通过这个引用,我们可以操作和访问对象的成员变量和方法。
需要注意的是,对象的创建过程是在运行时动态发生的,而不是在编译时确定的。因此,每次使用new
关键字创建对象时,都会在堆内存中为对象分配独立的内存空间,并执行相应的初始化和构造过程。每个对象都有自己独立的状态和数据。
另外,Java中的垃圾回收(Garbage Collection)机制会负责回收不再使用的对象的内存空间,以避免内存泄漏和提供自动内存管理。当对象不再被引用时,垃圾回收器会自动回收对象所占用的内存空间,并释放资源。
8. 什么是继承?
继承(Inheritance)是一种面向对象编程的概念,用于创建新的类从现有类继承属性和方法。通过继承,子类可以使用父类已有的功能,并可以在此基础上添加新的功能或修改已有的功能。
在Java中,使用关键字extends
来实现类的继承关系。子类可以继承父类的非私有成员变量和方法,包括字段、方法和构造函数。
Java中的继承是单继承的,一个类只能继承一个父类。但是,Java提供了接口(Interface)来实现多继承的效果,一个类可以实现多个接口。
继承的主要优势包括:
- // 父类
- class Animal {
- protected String name;
-
- public Animal(String name) {
- this.name = name;
- }
-
- public void eat() {
- System.out.println(name + " is eating.");
- }
- }
-
- // 子类
- class Dog extends Animal {
- public Dog(String name) {
- super(name);
- }
-
- public void bark() {
- System.out.println(name + " is barking.");
- }
- }

9. super 和 this
super
和this
都是关键字,在Java中用于访问类的不同成员或调用不同的构造函数。
super
关键字:
super
关键字来访问父类的成员变量和方法。super
时,可以调用父类的构造函数,以便在子类的构造函数中执行父类的初始化操作。super
的用法有两种:
super.成员名
,例如:super.name
表示访问父类的名为name
的成员变量。super(参数列表)
,例如:super(name, age)
表示调用父类带有name
和age
参数的构造函数。this
关键字:
this
关键字指代当前对象的引用,即调用当前方法或访问当前对象的成员变量。this
关键字来访问当前对象的成员变量或调用其他实例方法。this
关键字来调用当前类的其他构造函数。这种用法被称为构造函数的重载,用于复用代码和提供不同的构造方式。this
的用法有两种:
this.成员名
,例如:this.name
表示访问当前对象的名为name
的成员变量。this(参数列表)
,例如:this(name)
表示调用当前类带有name
参数的构造函数。需要注意的是,super
和this
关键字不能在静态方法(static
方法)中使用,因为静态方法属于类本身,没有实例化对象。它们只能在实例方法和构造函数中使用。
10. 什么是多态?
多态(Polymorphism)是面向对象编程的重要概念之一,它允许使用父类的引用变量来引用子类的对象,从而实现同一操作在不同对象上的多种形态。
多态的实现依赖于以下两个关键概念:
继承(Inheritance):通过继承,子类可以继承父类的属性和方法。子类对象可以被赋值给父类引用变量。
方法重写(Method Overriding):子类可以重写父类的方法,提供自己的实现。方法重写要求子类方法具有与父类方法相同的名称、参数列表和返回类型。
通过多态,可以实现以下特性:
1. 向上转型(Upcasting):子类对象可以赋值给父类引用变量。这样做可以将子类对象视为父类对象,从而使用父类的方法和属性。这种转型是隐式的,不需要显式的类型转换。
ParentClass obj = new ChildClass();
2. 方法的动态绑定(Dynamic Binding):当通过父类引用调用被子类重写的方法时,实际执行的是子类的方法。在运行时,JVM会根据对象的实际类型来决定调用哪个方法。
- ParentClass obj = new ChildClass();
- obj.method(); // 子类的method()方法被调用
多态的优势和应用场景包括:
代码的灵活性和扩展性:多态允许在父类引用的基础上处理不同的子类对象,使代码更灵活和可扩展。可以通过修改父类引用的指向来适应不同的对象类型。
统一的接口和封装:多态通过共享父类的接口,使得不同的对象可以以一致的方式进行访问和操作。这提供了更好的封装和抽象能力。
代码的可读性和可维护性:多态可以使代码更简洁、可读性更高,减少重复的代码和条件判断。
需要注意的是,多态只适用于针对父类的方法和属性。在多态的情况下,子类特有的方法和属性无法通过父类引用访问。如果需要访问子类特有的方法或属性,可以使用类型转换操作将父类引用转换为子类引用,以便调用子类特有的成员。
11. 访问权限
在Java中,访问权限用于控制类、成员变量、方法和构造函数对其他类和代码的可见性和可访问性。Java中有四种访问权限修饰符:
public
:使用public
修饰的类、成员变量、方法和构造函数可以被任何其他类访问。
protected
:被protected
修饰的成员变量、方法和构造函数可以在同一包内的其他类中被访问,以及在子类中被访问。
默认(包级)访问权限:如果没有指定访问权限修饰符,那么默认的访问权限会应用。默认访问权限限制了只有同一包内的其他类可以访问。
private
:私有访问权限是最严格的权限级别。使用private
修饰的成员变量、方法和构造函数只能在所属类内部访问,其他任何类都无法直接访问。
访问权限 | 同一类 | 同一包 | 子类 | 其他包 |
---|---|---|---|---|
public | ✓ | ✓ | ✓ | ✓ |
protected | ✓ | ✓ | ✓ | ✕ |
默认(包级) | ✓ | ✓ | ✕ | ✕ |
private | ✓ | ✕ | ✕ | ✕ |
12. 什么是抽象?
抽象(Abstraction)是一种面向对象编程的重要概念,它允许我们从具体的实现中提取出通用的概念和行为,并将其表示为抽象类或接口。抽象提供了一种封装和抽象化的方式,使得我们能够以更高层次的抽象思维来设计和组织代码。
抽象类(Abstract Class):
abstract
关键字修饰的类,无法被实例化。abstract
关键字修饰。接口(Interface):
interface
关键字定义。implements
关键字实现接口。抽象的优点和应用场景包括:
13. 什么是Bean规范?
Bean规范是Java语言中用于描述可重用组件的一种规范。它定义了一种用于封装数据和功能的标准化编程模型,称为JavaBean。JavaBean是一种符合特定规范的普通Java类,具有以下特征:
公共无参构造函数:JavaBean类必须提供一个公共的无参构造函数,用于实例化对象。
私有成员变量:JavaBean类的属性应该是私有的,并通过公共的访问方法(getter和setter)来访问和修改属性的值。
公共访问方法:JavaBean类应该提供公共的访问方法(getter和setter)来获取和设置属性的值。
序列化支持:JavaBean类可以实现java.io.Serializable
接口,以支持对象的序列化和反序列化。
符合命名规范:JavaBean类的命名应该符合标识符命名规范,属性名以小写字母开头,遵循驼峰命名法。
JavaBean规范的设计目的是提供一种通用的编程模型,使得Java类可以被简单地组织、配置和重用。JavaBean可用于各种应用领域,例如图形界面编程、Web开发和企业级应用开发等。
14. 说说作用域
作用域是指变量、方法、类等程序元素的可见范围,即它们可以被访问的代码范围。Java中有四种主要的作用域:
类级别作用域(Class-level Scope):
static
关键字来修饰。对象级别作用域(Object-level Scope):
方法级别作用域(Method-level Scope):
块级别作用域(Block-level Scope):
{}
包围的一段代码)内部声明的变量的范围。15. 说说java中的字符串操作
字符串的创建:
String str = "Hello";
new
关键字创建字符串对象:String str = new String("Hello");
字符串连接和拼接:
+
操作符进行字符串连接:String result = str1 + str2;
concat()
方法拼接字符串:String result = str1.concat(str2);
StringBuilder
或StringBuffer
类进行高效的字符串拼接。字符串的长度和字符获取:
length()
方法获取字符串的长度:int length = str.length();
charAt()
方法获取指定位置的字符:char ch = str.charAt(index);
字符串的比较:
equals()
方法比较字符串内容是否相等:boolean isEqual = str1.equals(str2);
equalsIgnoreCase()
方法忽略大小写进行比较:boolean isEqual = str1.equalsIgnoreCase(str2);
字符串的查找和替换:
indexOf()
方法查找指定字符或字符串的位置:int index = str.indexOf("search");
lastIndexOf()
方法从后往前查找指定字符或字符串的位置。replace()
方法替换字符串中的字符或字符串:String replaced = str.replace("old", "new");
字符串的分割和连接:
split()
方法将字符串分割成字符串数组:String[] parts = str.split(delimiter);
join()
方法将字符串数组连接成一个字符串:String joined = String.join(delimiter, strArray);
字符串的切割和子串提取:
substring()
方法提取子串:String sub = str.substring(startIndex, endIndex);
字符串的格式化:
printf()
方法进行字符串格式化输出:System.out.printf("Name: %s, Age: %d", name, age);
需要注意的是,Java中的字符串是不可变的(immutable),即字符串对象创建后不可修改。因此,对字符串的任何修改都会创建一个新的字符串对象。为了避免频繁的字符串对象创建,可以使用StringBuilder
或StringBuffer
类进行可变字符串的操作,与String类不同,StringBuilder允许对字符串进行动态修改,包括追加、插入、删除和替换等操作,而不会创建新的字符串对象。
16. int 和 Integer 的区别?
数据类型:
可赋值性:
int num = 10;
Integer number = new Integer(10);
或 Integer number = 10;
空值表示:
Integer number = null;
自动装箱和拆箱:
Integer number = 10;
(自动装箱),int num = number;
(自动拆箱)方法调用:
Integer.parseInt("10");
需要注意的是,尽管可以进行自动装箱和拆箱操作,但频繁地进行装箱和拆箱可能会带来一定的性能开销。因此,在需要高效处理大量整数计算时,建议使用基本数据类型int。而在需要更多操作和特性的场景下,使用Integer对象可以更方便地处理。
17. 说说 java.time.LocalTime 类
由于Date
类和Calendar
类在某些方面存在设计上的缺陷,不推荐使用,在Java 8及以上版本,建议使用java.time
包中的类来处理日期和时间。
java.time.LocalTime
是Java 8及以上版本引入的类,位于java.time
包中,用于表示时间值,不包含日期和时区信息。LocalTime
提供了许多方法来处理和操作时间,具有良好的可读性和线程安全性。
以下是LocalTime
类的一些重要特点和常用方法:
创建LocalTime
对象:
of()
创建指定的时间对象,例如:LocalTime time = LocalTime.of(hour, minute, second)
。now()
方法获取当前时间,或者使用解析方法parse()
将字符串解析为LocalTime
对象。获取时间的部分值:
getHour()
、getMinute()
、getSecond()
等方法获取时间的小时、分钟、秒等部分的值。getNano()
方法获取纳秒部分的值。时间的比较和判断:
compareTo()
方法比较两个LocalTime
对象的先后关系。isBefore()
、isAfter()
和equals()
等方法判断时间的先后和相等关系。时间的计算和调整:
plusHours()
、plusMinutes()
、minusSeconds()
等方法对时间进行加减操作。withHour()
、withMinute()
、withSecond()
等方法调整时间的部分值。格式化和解析时间:
format()
方法将LocalTime
对象格式化为字符串。parse()
将字符串解析为LocalTime
对象。需要注意的是,LocalTime
类表示的是本地时间,不包含时区信息。如果需要处理带有时区的时间,可以使用java.time.ZonedDateTime
类。
使用LocalTime
类获取当前时间并进行格式化的示例代码如下:
- import java.time.LocalTime;
- import java.time.format.DateTimeFormatter;
-
- public class Main {
- public static void main(String[] args) {
- // 获取当前时间
- LocalTime currentTime = LocalTime.now();
-
- // 定义时间格式
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
-
- // 格式化时间
- String formattedTime = currentTime.format(formatter);
-
- // 输出格式化后的时间
- System.out.println("当前时间:" + formattedTime);
- }
- }

18. Integer缓存
在Java中,Integer
类提供了一个整数缓存机制,可以重用一定范围内的整数对象,以减少内存消耗和对象创建的开销。这个整数缓存是通过Integer
类中的一个内部静态类实现的,称为IntegerCache
。
IntegerCache
缓存了从-128到127范围内的整数对象,默认情况下,这些整数对象在第一次使用时会被自动创建并缓存起来。当我们使用Integer
类的valueOf()
方法创建一个处于该范围内的整数时,实际上是从缓存中获取已经存在的对象,而不是创建新的对象。
这个缓存机制的设计是为了提高性能和节省内存。由于整数在编程中经常被使用,重复创建新的整数对象会造成不必要的内存开销。通过缓存已有的整数对象,可以减少内存占用,并提高性能。
需要注意的是,这个整数缓存机制只适用于Integer
类的自动装箱操作,即将int
类型的值自动转换为Integer
对象。如果使用new Integer()
显式创建Integer
对象,将不会使用缓存机制,而是创建一个新的对象。
以下是一个使用Integer
缓存的示例代码:
- Integer num1 = 10; // 自动装箱,从缓存中获取已有的Integer对象
- Integer num2 = 10; // 从缓存中获取已有的Integer对象
-
- System.out.println(num1 == num2); // 输出:true,两个引用指向同一个对象
-
- Integer num3 = 200; // 超过缓存范围,创建新的Integer对象
- Integer num4 = 200; // 超过缓存范围,创建新的Integer对象
-
- System.out.println(num3 == num4); // 输出:false,两个引用指向不同的对象
19. 说说java中的异常
在Java中,异常(Exception)是指程序在运行时遇到的意外情况或错误。异常是一种中断正常程序执行流程的事件,它可能导致程序终止或产生错误结果。
Java中的异常可以分为两种类型:已检查异常(Checked Exception)和未检查异常(Unchecked Exception)。
已检查异常(Checked Exception):
try-catch
块或在方法签名中使用throws
关键字声明。IOException
、SQLException
等。未检查异常(Unchecked Exception):
RuntimeException
类及其子类的实例。NullPointerException
、ArithmeticException
等。异常处理在Java中使用了以下关键字和结构:
try-catch
块:
try-catch
块可以捕获并处理异常。try
块用于包含可能引发异常的代码。catch
块用于捕获并处理异常,提供相应的处理逻辑。catch
块捕获不同类型的异常。finally
块定义无论是否发生异常都需要执行的代码块。throws
关键字:
throws
关键字可以将异常的处理责任交给调用方。throws
声明可能会抛出的异常类型,告知调用方需要处理这些异常。自定义异常:
Exception
类或其子类来自定义异常类。需要注意的是,捕获和处理异常应该是有针对性的,避免将所有异常都捕获到一个通用的catch
块中。
20. 常见的异常有哪些?
NullPointerException(空指针异常):
IllegalArgumentException(非法参数异常):
ArrayIndexOutOfBoundsException(数组下标越界异常):
ClassCastException(类转换异常):
ArithmeticException(算术异常):
FileNotFoundException(文件未找到异常):
IOException(输入输出异常):
InterruptedException(线程中断异常):
Thread.sleep()
方法时被中断或调用Thread.interrupt()
方法。除了上述异常外,还有许多其他类型的异常,如NumberFormatException(数字格式异常)、IllegalStateException(非法状态异常)、OutOfMemoryError(内存溢出错误)等,每种异常都有特定的原因和使用场景。
下一篇:JavaSE高级
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。