当前位置: 首页 > news >正文

Java基础知识

概念

请介绍全局变量和局部变量的区别

Java中的变量分为成员变量和局部变量,它们的区别如下:

成员变量:

1. 成员变量是在类的范围里定义的变量;

2. 成员变量有默认初始值;

3. 未被static修饰的成员变量也叫实例变量,它存储于对象所在的堆内存中,生命周期与对象相同;

4. 被static修饰的成员变量也叫类变量,它存储于方法区中,生命周期与当前类相同。

局部变量:

1. 局部变量是在方法里定义的变量;

2. 局部变量没有默认初始值;

3. 局部变量存储于栈内存中,作用的范围结束,变量空间会自动的释放

String可以被继承吗?

private final byte[] value

String类由final修饰,所以不能被继承。

在Java中,String类被设计为不可变类,主要表现在它保存字符串的成员变量是final的因为要保证String类的不可变,那么将这个类定义为final的就很容易理解了。如果没有final修饰,那么就会存在String的子类,这些子类可以重写String类的方法,强行改变字符串的值,这便违背了String类设计的初衷

使用字符串时,new和""推荐使用哪种方式?

先看看 "hello" 和 new String("hello") 的区别:

当Java程序直接使用 "hello" 的字符串直接量时,JVM将会使用常量池来管理这个字符串;

当使用 new String("hello") 时,JVM会先使用常量池来管理 "hello" 直接量,再调用String类的构造器来创建一个新的String对象,新创建的String对象被保存在堆内存中。 显然,采用new的方式会多创建一个对象出来,会占用更多的内存,所以一般建议使用直接量的方式创建字符串。

String a = "abc"; ,说一下这个过程会创建什么,放在哪里?

JVM会使用常量池来管理字符串直接量。

在执行这句话时,JVM会先检查常量池中是否已经存有"abc",

若没有则将"abc"存入常量池,否则就复用常量池中已有的"abc",将其引用赋值给变量a。

new String("abc") 是去了哪里,仅仅是在堆里面吗?

在执行这句话时,JVM会先使用常量池来管理字符串直接量,即将"abc"存入常量池。然后再创建一个新的String对象,这个对象会被保存在堆内存中。并且,堆中对象的数据会指向常量池中的直接量

说一下Java的特点

主要有以下的特点:

平台无关性:Java的“编写一次,运行无处不在”哲学是其最大的特点之一。Java编译器将源代码编译成字节码(bytecode),该字节码可以在任何安装了Java虚拟机(JVM)的系统上运行。

面向对象:Java是一门严格的面向对象编程语言,几乎一切都是对象。面向对象编程(OOP)特性使得代码更易于维护和重用,包括类(class)、对象(object)、继承(inheritance)、多态(polymorphism)、抽象(abstraction)和封装(encapsulation)。

内存管理:Java有自己的垃圾回收机制,自动管理内存和回收不再使用的对象。这样,开发者不需要手动管理内存,从而减少内存泄漏和其他内存相关的问题。

Java为什么是跨平台的?

Java 能支持跨平台,主要依赖于 JVM 关系比较大。

JVM也是一个软件,不同的平台有不同的版本。我们编写的Java源码,编译后会生成一种 .class 文件,称为字节码文件。Java虚拟机就是负责将字节码文件翻译成特定平台下的机器码然后运行。也就是说,只要在不同平台上安装对应的JVM,就可以运行字节码文件,运行我们编写的Java程序。

而这个过程中,我们编写的Java程序没有做任何改变,仅仅是通过JVM这一”中间层“,就能在不同平台上运行,真正实现了”一次编译,到处运行“的目的。

JVM是一个”桥梁“,是一个”中间件“,是实现跨平台的关键,Java代码首先被编译成字节码文件,再由JVM将字节码文件翻译成机器语言,从而达到运行Java程序的目的。

编译的结果不是生成机器码,而是生成字节码,字节码不能直接运行,必须通过JVM翻译成机器码才能运行。不同平台下编译生成的字节码是一样的,但是由JVM翻译成的机器码却不一样。

所以,运行Java程序必须有JVM的支持,因为编译的结果不是机器码,必须要经过JVM的再次翻译才能执行。即使你将Java程序打包成可执行文件(例如 .exe),仍然需要JVM的支持。

JVM、JDK、JRE三者关系?

它们之间的关系如下:

JVM是Java虚拟机,是Java程序运行的环境。它负责将Java字节码(由Java编译器生成)解释或编译成机器码,并执行程序。JVM提供了内存管理、垃圾回收、安全性等功能,使得Java程序具备跨平台性。

JDK是Java开发工具包,是开发Java程序所需的工具集合。它包含了JVM、编译器(javac)、调试器(jdb)等开发工具,以及一系列的类库(如Java标准库和开发工具库)。JDK提供了开发、编译、调试和运行Java程序所需的全部工具和环境。

JRE是Java运行时环境,是Java程序运行所需的最小环境。它包含了JVM和一组Java类库,用于支持Java程序的执行。JRE不包含开发工具,只提供Java程序运行所需的运行环境。

为什么Java解释和编译都有?

编译性:

Java源代码首先被编译成字节码,JIT 会把编译过的机器码保存起来,以备下次使用。

解释性:

JVM中一个方法调用计数器,当累计计数大于一定值的时候,就使用JIT进行编译生成机器码文件。否则就是用解释器进行解释执行,然后字节码也是经过解释器进行解释运行的。

所以Java既是编译型也是解释性语言,默认采用的是解释器和编译器混合的模式。

jvm是什么

JVM是 java 虚拟机,主要工作是解释自己的指令集(即字节码)并映射到本地的CPU指令集和OS的系统调用。

JVM屏蔽了与操作系统平台相关的信息,使得Java程序只需要生成在Java虚拟机上运行的目标代码(字节码),就可在多种平台上不加修改的运行,这也是Java能够“一次编译,到处运行的”原因。

编译型语言和解释型语言的区别?

编译型语言和解释型语言的区别在于:

编译型语言:在程序执行之前,整个源代码会被编译成机器码或者字节码,生成可执行文件。执行时直接运行编译后的代码,速度快,但跨平台性较差。

解释型语言:在程序执行时,逐行解释执行源代码不生成独立的可执行文件。通常由解释器动态解释并执行代码,跨平台性好,但执行速度相对较慢。

典型的编译型语言如C、C++,典型的解释型语言如Python、JavaScript。

Python和Java区别是什么?

Java是一种已编译的编程语言,Java编译器将源代码编译为字节码,而字节码则由Java虚拟机执行

python是一种解释语言,翻译时会在执行程序的同时进行翻译。

数据类型

八种基本的数据类型

Java支持数据类型分为两类: 基本数据类型和引用数据类型。

基本数据类型共有8种,可以分为三类:

数值型:整数类型(byte、short、int、long)和浮点类型(float、double)

字符型:char

布尔型:boolean

long和int可以互转吗 ?

可以的,Java中的long和int可以相互转换。由于long类型的范围比int类型大,因此将int转换为long是安全的,而将long转换为int可能会导致数据丢失或溢出。

将int转换为long可以通过直接赋值或强制类型转换来实现。例如:

int intValue = 10;

long longValue = intValue; // 自动转换,安全的

将long转换为int需要使用强制类型转换,但需要注意潜在的数据丢失或溢出问题。

long longValue = 100L;

int intValue = (int) longValue; // 强制类型转换,可能会有数据丢失或溢出

数据类型转换方式你知道哪些?

自动类型转换(隐式转换):当目标类型的范围大于源类型时,Java会自动将源类型转换为目标类型,不需要显式的类型转换。例如,将int转换为long、将float转换为double等。

强制类型转换(显式转换):当目标类型的范围小于源类型时,需要使用强制类型转换将源类型转换为目标类型。这可能导致数据丢失或溢出。例如,将long转换为int、将double转换为int等。语法为:目标类型 变量名 = (目标类型) 源类型。

字符串转换:Java提供了将字符串表示的数据转换为其他类型数据的方法。例如,将字符串转换为整型int,可以使用Integer.parseInt()方法;将字符串转换为浮点型double,可以使用Double.parseDouble()方法等。

数值之间的转换:Java提供了一些数值类型之间的转换方法,如将整型转换为字符型、将字符型转换为整型等。这些转换方式可以通过类型的包装类来实现,例如Character类、Integer类等提供了相应的转换方法。

类型互转会出现什么问题吗?

数据丢失当将一个范围较大的数据类型转换为一个范围较小的数据类型时,可能会发生数据丢失。例如,将一个long类型的值转换为int类型时,如果long值超出了int类型的范围,转换结果将是截断后的低位部分,高位部分的数据将丢失。

数据溢出与数据丢失相反,当将一个范围较小的数据类型转换为一个范围较大的数据类型时,可能会发生数据溢出。例如,将一个int类型的值转换为long类型时,转换结果会填充额外的高位空间,但原始数据仍然保持不变。

精度损失:在进行浮点数类型的转换时,可能会发生精度损失。由于浮点数的表示方式不同,将一个单精度浮点数(float)转换为双精度浮点数(double)时,精度可能会损失。

类型不匹配导致的错误:在进行类型转换时,需要确保源类型和目标类型是兼容的。如果两者不兼容,会导致编译错误或运行时错误。

为什么用bigDecimal 不用double ?

double会出现精度丢失的问题

而 Decimal 是精确计算 , 所以一般牵扯到金钱的计算 , 都使用 Decimal。

装箱和拆箱是什么?

装箱(Boxing)和拆箱(Unboxing)是将基本数据类型和对应的包装类之间进行转换的过程。

Integer i = 10;  //装箱

int n = i;   //拆箱

自动装箱主要发生在两种情况,一种是赋值时,另一种是在方法调用的时候。

赋值时

这是最常见的一种情况,在Java 1.5以前我们需要手动地进行转换才行,而现在所有的转换都是由编译器来完成。

方法调用时

当我们在方法调用时,我们可以传入原始数据值或者对象,同样编译器会帮我们进行转换。

public static Integer show(Integer iParam){

   System.out.println("autoboxing example - method invocation i: " + iParam);

   return iParam;

}

自动装箱的弊端

自动装箱有一个问题,那就是在一个循环中进行自动装箱操作的情况,如下面的例子就会创建多余的对象,影响程序的性能。

Integer sum = 0; for(int i=1000; i<5000; i++){   sum+=i; }

上面的代码sum+=i可以看成sum = sum + i,但是+这个操作符不适用于Integer对象,首先sum进行自动拆箱操作,进行数值相加操作,最后发生自动装箱操作转换成Integer对象。其内部变化如下

int result = sum.intValue() + i; Integer sum = new Integer(result);

由于我们这里声明的sum为Integer类型,在上面的循环中会创建将近4000个无用的Integer对象,在这样庞大的循环中,会降低程序的性能并且加重了垃圾回收的工作量。因此在我们编程时,需要注意到这一点,正确地声明变量类型,避免因为自动装箱引起的性能问题。

Java为什么要有Integer?

Integer对应是int类型的包装类,就是把int类型包装成Object对象,对象封装有很多好处,可以把属性也就是数据跟处理这些数据的方法结合在一起,比如Integer就有parseInt()等方法来专门处理int型相关的数据。

另一个非常重要的原因就是在Java中绝大部分方法或类都是用来处理类类型对象的,如ArrayList集合类就只能以类作为他的存储对象,而这时如果想把一个int型的数据存入list是不可能的,必须把它包装成类,也就是Integer才能被List所接受。所以Integer的存在是很必要的。

Integer相比int有什么优点?

Integer和 int 的区别:

使用int来存储一个整数时,不需要任何额外的内存分配,而使用Integer时,必须为对象分配内存。在性能方面,基本数据类型的操作通常比相应的引用类型快。

那为什么还要保留int类型?

不管是读写效率,还是存储效率,基本类型都比包装类高效。

说一下 integer的缓存

Java的Integer类内部实现了一个静态缓存池,用于存储特定范围内的整数值对应的Integer对象。

默认情况下,这个范围是-128至127。当通过Integer.valueOf(int)方法创建一个在这个范围内的整数对象时,并不会每次都生成新的对象实例,而是复用缓存中的现有对象,会直接从内存中取出,不需要新建一个对象。

Integer a = 127;

Integer b = 127;

Integer c = 128;

Integer d = 128;

System.out.println(a == b);

System.out.println(c == d);

面向对象

怎么理解面向对象?简单说说封装继承多态

洗衣服: 人(把衣服放进洗衣机),洗衣机(洗衣服)

面向对象是一种编程范式,它将现实世界中的事物抽象为对象,对象具有属性(称为字段或属性)和行为(称为方法)。面向对象编程的设计思想是以对象为中心,通过对象之间的交互来完成程序的功能,具有灵活性和可扩展性,通过封装和继承可以更好地应对需求变化。

Java面向对象的三大特性包括:封装、继承、多态:

封装:通过关键字private,对外隐藏对象的内部细节,仅通过对象提供的接口与外界交互。

继承:对共性进行抽取,达到代码的复用

多态:相同类型的对象调用同一个方法会产生不同的状态

多态体现在哪几个方面?

多态在面向对象编程中可以体现在以下几个方面:

方法重载:

方法名相同,参数列表不同,返回值不做要求

方法重写:

方法名相同,参数列表相同,返回值相同或者具有父子关系

向上转型

在Java中,可以使用父类类型的引用指向子类对象,这是向上转型。直接赋值,方法传参,返回值

多态解决了什么问题?

多态是指子类可以替换父类,在实际的代码运行过程中,调用子类的方法实现。多态这种特性也需要编程语言提供特殊的语法机制来实现,比如继承、接口类。

多态可以提高代码的扩展性和复用性,是很多设计模式、设计原则、编程技巧的代码实现基础。比如策略模式、基于接口而非实现编程、依赖倒置原则、里式替换原则、利用多态去掉冗长的 if-else 语句等等

重载与重写有什么区别?

方法重载:

方法名相同,参数列表不同,返回值不做要求

方法重写:

方法名相同,参数列表相同,返回值相同或者具有父子关系

Java抽象类和接口的区别是什么?

从使用方式上来说,二者有如下的区别:

接口里只能包含抽象方法、静态方法、默认方法和私有方法,不能为普通方法提供方法实现;抽象类则完全可以包含普通方法。

接口里只能定义静态常量,不能定义普通成员变量;抽象类里则既可以定义普通成员变量,也可以定义静态常量。

接口里不包含构造器;抽象类里可以包含构造器,抽象类里的构造器并不是用于创建对象,而是让其子类调用这些构造器来完成属于抽象类的初始化操作。

接口里不能包含初始化块;但抽象类则完全可以包含初始化块。

一个类最多只能有一个直接父类,包括抽象类;但一个类可以直接实现多个接口,通过实现多个接口可以弥补Java单继承的不足。

接口和抽象类很像,它们都具有如下共同的特征:

接口和抽象类都不能被实例化,它们都位于继承树的顶端,用于被其他类实现和继承。

接口和抽象类都可以包含抽象方法,实现接口或继承抽象类的普通子类都必须实现这些抽象方法。

抽象类能加final修饰吗?

不能,Java中的抽象类是用来被继承的,而final修饰符用于禁止类被继承或方法被重写,因此,抽象类和final修饰符是互斥的,不能同时使用。

解释Java中的静态变量和静态方法

在Java中,静态变量和静态方法是与类本身关联的,而不是与类的实例(对象)关联。它们在内存中只存在一份,可以被类的所有实例共享。

静态变量

静态变量(也称为类变量)是在类中使用static关键字声明的变量。它们属于类而不是任何具体的对象。主要的特点:

共享性:所有该类的实例共享同一个静态变量。如果一个实例修改了静态变量的值,其他实例也会看到这个更改。

初始化:静态变量在类被加载时初始化,只会对其进行一次分配内存。

访问方式:静态变量可以直接通过类名访问,也可以通过实例访问,但推荐使用类名。

静态方法

静态方法是在类中使用static关键字声明的方法。类似于静态变量,静态方法也属于类,而不是任何具体的对象。主要的特点:

无实例依赖:静态方法可以在没有创建类实例的情况下调用。对于静态方法来说,不能直接访问非静态的成员变量或方法,因为静态方法没有上下文的实例。

访问静态成员:静态方法可以直接调用其他静态变量和静态方法,但不能直接访问非静态成员。

多态性:静态方法不支持重写(Override),但可以被隐藏(Hide)。

使用场景

静态变量:常用于需要在所有对象间共享的数据,如计数器、常量等。

静态方法:常用于助手方法(utility methods)、获取类级别的信息或者是没有依赖于实例的数据处理。

非静态内部类和静态内部类的区别?

区别包括:

非静态内部类依赖于外部类的实例,而静态内部类不依赖于外部类的实例。

非静态内部类可以访问外部类的实例变量和方法,而静态内部类只能访问外部类的静态成员。

非静态内部类不能定义静态成员,而静态内部类可以定义静态成员。

非静态内部类可以直接访问外部方法,编译器是怎么做到的?

非静态内部类可以直接访问外部方法是因为编译器在生成字节码时会为非静态内部类维护一个指向外部类实例的引用。

有一个父类和子类,都有静态的成员变量、静态构造方法和静态方法,在我new一个子类对象的时候,加载顺序是怎么样的?

当你实例化一个子类对象时,静态成员变量、静态构造方法和静态方法的加载顺序遵循以下步骤:

父类静态成员变量、静态代码块(如果有)

子类静态成员变量、静态代码块(如果有)

父类构造方法(实例化对象时)

子类构造方法(实例化对象时)

深拷贝和浅拷贝

深拷贝和浅拷贝的区别?

浅拷贝是指只复制对象本身和其内部的值类型字段,但不会复制对象内部的引用类型字段。换句话说,浅拷贝只是创建一个新的对象,然后将原对象的字段值复制到新对象中,但如果原对象内部有引用类型的字段,只是将引用复制到新对象中,两个对象指向的是同一个引用对象。

深拷贝是指在复制对象的同时,将对象内部的所有引用类型字段的内容也复制一份,而不是共享引用。换句话说,深拷贝会递归复制对象内部所有引用类型的字段,生成一个全新的对象以及其内部的所有对象。

实现深拷贝的三种方法是什么?

在 Java 中,实现对象深拷贝的方法有以下几种主要方式:

实现 Cloneable 接口并重写 clone() 方法

这种方法要求对象及其所有引用类型字段都实现 Cloneable 接口,并且重写 clone() 方法。在 clone() 方法中,通过递归克隆引用类型字段来实现深拷贝。

使用序列化和反序列化

通过将对象序列化为字节流,再从字节流反序列化为对象来实现深拷贝。要求对象及其所有引用类型字段都实现 Serializable 接口。

泛型

什么是泛型?

泛型是 Java 编程语言中的一个重要特性,它允许类、接口和方法在定义时使用一个或多个类型参数,这些类型参数在使用时可以被指定为具体的类型

泛型的主要目的是在编译时提供更强的类型检查,并且在编译后能够保留类型信息,避免了在运行时出现类型转换异常。

为什么需要泛型?

适用于多种数据类型执行相同的代码

泛型中的类型在使用时指定,不需要强制类型转换(类型安全,编译器会检查类型)

对象

java创建对象有哪些方式?

在Java中,创建对象的方式有多种,常见的包括:

使用new关键字:通过new关键字直接调用类的构造方法来创建对象。

MyClass obj = new MyClass();

使用Class类的newInstance()方法:通过反射机制,可以使用Class类的newInstance()方法创建对象。

MyClass obj = (MyClass) Class.forName("com.example.MyClass").newInstance();

使用Constructor类的newInstance()方法:同样是通过反射机制,可以使用Constructor类的newInstance()方法创建对象。

Constructor<MyClass> constructor = MyClass.class.getConstructor();

MyClass obj = constructor.newInstance();

使用clone()方法:如果类实现了Cloneable接口,可以使用clone()方法复制对象。

New出的对象什么时候回收?

通过过关键字new创建的对象,由Java的垃圾回收器(Garbage Collector)负责回收。垃圾回收器的工作是在程序运行过程中自动进行的,它会周期性地检测不再被引用的对象,并将其回收释放内存。

具体来说,Java对象的回收时机是由垃圾回收器根据一些算法来决定的,主要有以下几种情况:

引用计数法:某个对象的引用计数为0时,表示该对象不再被引用,可以被回收。

可达性分析算法:从根对象(如方法区中的类静态属性、方法中的局部变量等)出发,通过对象之间的引用链进行遍历,如果存在一条引用链到达某个对象,则说明该对象是可达的,反之不可达,不可达的对象将被回收。

反射

什么是反射?

Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类中的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为 Java 语言的反射机制。

反射具有以下特性:

运行时类信息访问:反射机制允许程序在运行时获取类的完整结构信息,包括类名、包名、父类、实现的接口、构造函数、方法和字段等。

动态对象创建:可以使用反射API动态地创建对象实例,即使在编译时不知道具体的类名。这是通过Class类的newInstance()方法或Constructor对象的newInstance()方法实现的。

动态方法调用:可以在运行时动态地调用对象的方法,包括私有方法。这通过Method类的invoke()方法实现,允许你传入对象实例和参数值来执行方法。

访问和修改字段值:反射还允许程序在运行时访问和修改对象的字段值,即使是私有的。这是通过Field类的get()和set()方法完成的。

反射在你平时写代码或者框架中的应用场景有哪些?

加载数据库驱动

我们的项目底层数据库有时是用mysql,有时用oracle,需要动态地根据实际情况加载驱动类,这个时候反射就有用了,假设 com.mikechen.java.myqlConnection,com.mikechen.java.oracleConnection这两个类我们要用。

这时候我们在使用 JDBC 连接数据库时使用 Class.forName()通过反射加载数据库的驱动程序,如果是mysql则传入mysql的驱动类,而如果是oracle则传入的参数就变成另一个了。

配置文件加载

Spring 框架的 IOC(动态加载管理 Bean),Spring通过配置文件配置各种各样的bean,你需要用到哪些bean就配哪些,spring容器就会根据你的需求去动态加载,你的程序就能健壮地运行。

注解

能讲一讲Java注解的原理吗?

注解本质是一个继承了Annotation的特殊接口,其具体实现类是Java运行时生成的动态代理类。

我们通过反射获取注解时,返回的是Java运行时生成的动态代理对象。通过代理对象调用自定义注解的方法,会最终调用AnnotationInvocationHandler的invoke方法。该方法会从memberValues这个Map中索引出对应的值。而memberValues的来源是Java常量池。

Java注解的作用域呢?

注解的作用域(Scope)指的是注解可以应用在哪些程序元素上,例如类、方法、字段等。Java注解的作用域可以分为三种:

类级别作用域:用于描述类的注解,通常放置在类定义的上面,可以用来指定类的一些属性,如类的访问级别、继承关系、注释等。

方法级别作用域:用于描述方法的注解,通常放置在方法定义的上面,可以用来指定方法的一些属性,如方法的访问级别、返回值类型、异常类型、注释等。

字段级别作用域:用于描述字段的注解,通常放置在字段定义的上面,可以用来指定字段的一些属性,如字段的访问级别、默认值、注释等。

除了这三种作用域,Java还提供了其他一些注解作用域,例如构造函数作用域和局部变量作用域。这些注解作用域可以用来对构造函数和局部变量进行描述和注释。

异常

介绍一下Java异常

Java异常类层次结构图:Java的异常体系主要基于两大类:Throwable类及其子类。Throwable有两个重要的子类:Error和Exception,它们分别代表了不同类型的异常情况。

Error(错误):表示运行时环境的错误。错误是程序无法处理的严重问题,如系统崩溃、虚拟机错误、动态链接失败等。通常,程序不应该尝试捕获这类错误。例如,OutOfMemoryError、StackOverflowError等。

Exception(异常):表示程序本身可以处理的异常条件。异常分为两大类:

非运行时异常:这类异常在编译时期就必须被捕获或者声明抛出。它们通常是外部错误,如文件不存在(FileNotFoundException)、类未找到(ClassNotFoundException)等。非运行时异常强制程序员处理这些可能出现的问题,增强了程序的健壮性。

运行时异常:这类异常包括运行时异常(RuntimeException)和错误(Error)。运行时异常由程序错误导致,如空指针访问(NullPointerException)、数组越界(ArrayIndexOutOfBoundsException)等。运行时异常是不需要在编译时强制捕获或声明的。

编译时异常/受查异常

   程序员手动捕获或者throws进行处理

运行时异常/非受查异常

   不需要程序员手动处理,jvm会帮助处理

Java异常处理有哪些?

异常处理是通过使用try-catch语句块来捕获和处理异常。以下是Java中常用的异常处理方式:

try-catch语句块:用于捕获并处理可能抛出的异常。try块中包含可能抛出异常的代码,catch块用于捕获并处理特定类型的异常。可以有多个catch块来处理不同类型的异常。

throw语句:用于手动抛出异常。可以根据需要在代码中使用throw语句主动抛出特定类型的异常。

throw new ExceptionType("Exception message");

throws关键字:用于在方法声明中声明可能抛出的异常类型。如果一个方法可能抛出异常,但不想在方法内部进行处理,可以使用throws关键字将异常传递给调用者来处理。

抛出异常为什么不用throws?

如果异常是未检查异常或者在方法内部被捕获和处理了,那么就不需要使用throws。

Unchecked Exceptions:未检查异常(unchecked exceptions)是继承自RuntimeException类或Error类的异常,编译器不强制要求进行异常处理。因此,对于这些异常,不需要在方法签名中使用throws来声明。示例包括NullPointerException、ArrayIndexOutOfBoundsException等。

捕获和处理异常:另一种常见情况是,在方法内部捕获了可能抛出的异常,并在方法内部处理它们,而不是通过throws子句将它们传递到调用者。这种情况下,方法可以处理异常而无需在方法签名中使用throws。

try catch中的语句运行情况

try块中的代码将按顺序执行,如果抛出异常,将在catch块中进行匹配和处理,然后程序将继续执行catch块之后的代码。如果没有匹配的catch块,异常将被传递给上一层调用的方法。

try{return “a”} fianlly{return “b”}这条语句返回啥

finally块中的return语句会覆盖try块中的return返回,因此,该语句将返回"b"。

object

== 与 equals 有什么区别?

对于字符串变量来说,使用"=="和"equals"比较字符串时,其比较方法不同。"=="比较两个变量本身的值,即两个对象在内存中的首地址,"equals"比较字符串包含内容是否相同。

对于非字符串变量来说,如果没有对equals()进行重写的话,"==" 和 "equals"方法的作用是相同的,都是用来比较对象在堆内存中的首地址,即用来比较两个引用变量是否指向同一个对象。

==:比较的是两个字符串内存地址(堆内存)的数值是否相等,属于数值比较;

equals():比较的是两个字符串的内容,属于内容比较。

StringBuffer和StringBuild区别是什么?

区别:

线程安全:

StringBuffer:线程安全

StringBuilder:线程不安全

速度:

一般情况下,速度从快到慢为 StringBuilder > StringBuffer > String,当然这是相对的,不是绝对的。

使用场景:

操作少量的数据使用 String。

单线程操作大量数据使用 StringBuilder。

多线程操作大量数据使用 StringBuffer。

有一个学生类,想按照分数排序,再按学号排序,应该怎么做?

可以使用Comparable接口来实现按照分数排序,再按照学号排序。首先在学生类中实现Comparable接口,并重写compareTo方法,然后在compareTo方法中实现按照分数排序和按照学号排序的逻辑

相关文章:

Java基础知识

概念 请介绍全局变量和局部变量的区别 Java中的变量分为成员变量和局部变量&#xff0c;它们的区别如下&#xff1a; 成员变量&#xff1a; 1. 成员变量是在类的范围里定义的变量&#xff1b; 2. 成员变量有默认初始值&#xff1b; 3. 未被static修饰的成员变量也叫…...

体验智能体构建过程:从零开始构建Agent

1. 什么是智能体&#xff1f; 智能体&#xff08;Agents&#xff09;是一种能够感知环境、做出决策并采取行动来实现特定目标的自主实体。智能体的复杂程度各不相同&#xff0c;从简单的响应式智能体&#xff08;对刺激直接做出反应&#xff09;到更高级的智能体&#xff08;能…...

如何从项目目标到成功标准:构建可量化、可落地的项目评估体系

引言 在项目管理领域&#xff0c;"项目成功"的定义往往比表面看起来更复杂。根据PMI的行业报告&#xff0c;67%的项目失败源于目标与成功标准的不匹配。当项目团队仅关注"按时交付"或"预算达标"时&#xff0c;常会忽视真正的价值创造。本文将通…...

大模型论文:Language Models are Few-Shot Learners(GPT3)

大模型论文&#xff1a;Language Models are Few-Shot Learners(GPT3) 文章地址&#xff1a;https://proceedings.neurips.cc/paper_files/paper/2020/file/1457c0d6bfcb4967418bfb8ac142f64a-Paper.pdf 一、摘要 我们证明了&#xff0c;扩大语言模型的规模在任务无关的 few…...

驱动学习专栏--字符设备驱动篇--1_chrdevbase

字符设备驱动简介 字符设备是 Linux 驱动中最基本的一类设备驱动&#xff0c;字符设备就是一个一个字节&#xff0c;按照字节 流进行读写操作的设备&#xff0c;读写数据是分先后顺序的。比如我们最常见的点灯、按键、 IIC 、 SPI &#xff0c; LCD 等等都是字符设备&…...

muduo库源码分析: TcpConnection

一. 主要成员: socket_&#xff1a;用于保存已连接套接字文件描述符。channel_&#xff1a;封装了上面的socket_及其各类事件的处理函数&#xff08;读、写、错误、关闭等事件处理函数&#xff09;。这个Channel中保存的各类事件的处理函数是在TcpConnection对象构造函数中注册…...

【SLAM】ubuntu 18.04 编译安装 OpenCV 3.2.0 时出现哈希错误

本文首发于❄慕雪的寒舍 1. 前言 1.1. 问题说明 在amd64的ubuntu 18.04 desktop上编译安装 OpenCV 3.2.0 的时候&#xff0c;我遇到了cmake构建错误。错误的核心报错如下 for file: [/home/king/slam/pkg/opencv-3.2.0/3rdparty/ippicv/downloads/linux-808b791a6eac9ed78d32…...

挂马漏洞 asp连接冰蝎webshell (附webshell源码 仅限学习研究)

目录 ASP WebShell代码 代码说明&#xff1a; 部署步骤&#xff1a; 使用冰蝎客户端连接&#xff1a; 注意事项&#xff1a; ASP WebShell代码 <% 冰蝎连接密码&#xff08;需与冰蝎客户端配置一致&#xff09; Dim key key "mysecretkey123" 自定义密码…...

Grafana将弃用AngularJS-我们该如何迁移

AngularJS 弃用时间线 AngularJS 支持已在 Grafana 9 中正式弃用。在 2024 年 5 月发布的 Grafana 11 中&#xff0c;所有 Grafana Cloud 和自托管安装默认关闭该功能。到 Grafana 12 版本时&#xff0c;将完全移除对 AngularJS 的支持&#xff0c;包括配置参数开关 angular_s…...

基于单片机的病房呼叫系统设计

2.1 总体方案设计 本课题为基于单片机的病房呼叫系统设计&#xff0c;在此将整个系统架构设计如图2.1所示&#xff0c;在此采用八个按键模拟8个不同的病房号&#xff0c;再通过8个LED指示灯对病房号的状态进行指示&#xff0c;当用户按键按键时&#xff0c;相应的LED灯会点亮…...

简述一下Unity的UnityWebRequest

UnityWebRequest是Unity引擎中用于处理网络请求的强大工具&#xff0c;尤其适用于与Web服务器进行交互&#xff0c;比如获取数据、上传文件或下载资源等。相较于旧版的WWW类&#xff0c;UnityWebRequest提供了更灵活、更高效的API&#xff0c;支持多种HTTP方法&#xff0c;并能…...

文件操作和IO - 2

目录 Java 中操作文件 File 概述 属性 构造方法 方法 getParent getName getPath getAbsolutePath getCanonicalPath exists isFile isDirectory createNewFile delete deleteOnExit list listFiles mkdir mkdirs 完&#xff01; Java 中操作文件 Java 对于文件操…...

⑪数据中心网络M-LAG实战

一、DeviceA-M-LAG-Mater配置 1、M-LAG 系统配置。 # m-lag mad exclude interface GigabitEthernet1/0/7 m-lag mad exclude interface Vlan-interface100 m-lag mad exclude interface Vlan-interface101 m-lag system-mac 0002-0002-0002 m-lag system-number 1 m-la…...

Win10系统安装WSL2-Ubuntu, 并使用VScode开始工作

本教程基于博主当前需要使用 WSL2(Windows Subsystem for Linux 2) 而编写&#xff0c;将自己使用的经过分享给大家。有什么意见建议敬请大家批评指正。此过程需要打开 Microsoft Store 话不多说&#xff0c;立即开始~ 文章目录 1. 检查系统版本2. 启动 WSL 功能3. 安装Ubuntu4…...

Node.js种cluster模块详解

Node.js 中 cluster 模块全部 API 详解 1. 模块属性 const cluster require(cluster);// 1. isMaster // 判断当前进程是否为主进程 console.log(是否为主进程:, cluster.isMaster);// 2. isWorker // 判断当前进程是否为工作进程 console.log(是否为工作进程:, cluster.isW…...

Window 10使用WSL2搭建Linux版Android Studio应用开发环境

一、背景 公司基于高通SA8155、SA8295等车载芯片进行座舱系统开发,使用repo统一管理系统及应用源码仓库。 Android应用端使用Ubuntu环境Android Studio进行开发,使用repo进行平台性管理,包含所有应用仓库。由于gradle配置使用了linux下文件软链接,无法直接使用Window环境…...

PostgreSQL 的统计信息

PostgreSQL 的统计信息 PostgreSQL 的统计信息是查询优化和性能调优的基础&#xff0c;系统通过多种统计信息来评估数据分布和访问模式&#xff0c;从而生成高效的执行计划。 一 统计信息类型与用途 1.1 核心统计类别 统计类型存储位置主要用途更新机制表和索引扫描统计pg_…...

【Linux】Linux基础指令

Linux系统初步介绍 Linux是一种自由和开放源代码的类UNIX操作系统,该操作系统的内核由林纳斯托瓦兹在1991年首次发布,之后,在加上用户空间的应用程序之后,就成为了Linux操作系统&#xff61; 严格来讲,Linux 只是操作系统内核本身,但通常采用“Linux内核”来表达该意思&#…...

【SLAM】在ORB_SLAM2的ROS模式下使用RealSense D435相机

本文介绍了如何在ORB_SLAM2项目中使用RealSense D435相机作为RGB-D输入源&#xff0c;包括ROS下启动D435相机、ORB_SLAM2订阅Topic、ORB_SLAM2读取realsense-viewer录制的rosbag文件等步骤。。 本文首发于❄慕雪的寒舍 1. 前言 先前已经编写了如何用TUM数据集运行ORB_SLAM3以及…...

scapy使用

https://scapy.readthedocs.io/en/latest/introduction.html 在 Mac 上使用 Scapy 抓取特定 IP 的流量并保存到 a.pcap 的步骤如下&#xff1a; 步骤 1&#xff1a;安装 Scapy 在终端中执行以下命令安装&#xff1a; pip install scapy步骤 2&#xff1a;创建 Python 脚本 …...

C2000 系统控制(4) — CPU Memory

CPU 内存 内存控制器 在 C2000 实时微控制器上&#xff0c;RAM 具有不同的特性。这些特性包括&#xff1a; CPU 专用&#xff1a;M0、M1 RAMCPU 和 CLA 共享&#xff1a;LSx RAMCPU、DMA 和 HIC 共享&#xff1a;GSx RAM用于在处理器之间发送和接收消息&#xff1a;MSG RAM …...

Linux网络编程——详解网络层IP协议、网段划分、路由

目录 一、前言 二、IP协议的认识 1、什么是IP协议&#xff1f; 2、IP协议报头 三、网段划分 1、初步认识IP与路由 2、IP地址 I、DHCP动态主机配置协议 3、IP地址的划分 I、CIDR设计 II、子网数目的计算 III、子网掩码的确定 四、特殊的IP地址 五、IP地址的数量限…...

解析医疗器械三大文档:DHF、DMR与DHR

医疗器械的 DHF、DMR 和 DHR 是质量管理体系&#xff08;QMS&#xff09;中的核心文件&#xff0c;贯穿产品全生命周期&#xff0c; 确保医疗器械的安全性、有效性和合规性。 一、三大文件的定义与法规依据 缩写全称法规依据&#xff08;以 FDA 为例&#xff09;核心目的DHF…...

SQL 全文检索原理

全文检索(Full-Text Search)是SQL中用于高效搜索文本数据的技术&#xff0c;与传统的LIKE操作或简单字符串比较相比&#xff0c;它能提供更强大、更灵活的文本搜索能力。 基本概念 全文检索的核心思想是将文本内容分解为可索引的单元(通常是词或词组)&#xff0c;然后建立倒排…...

基于Rosen梯度投影法的约束优化问题求解及MATLAB实现

摘要 在工程优化、经济建模等领域&#xff0c;约束优化问题普遍存在&#xff0c;其核心是在满足线性或非线性约束条件下求解目标函数的极值。本文聚焦Rosen梯度投影法&#xff0c;系统阐述其算法原理、实现步骤及MATLAB编程方法。 关键词&#xff1a;Rosen梯度投影法&#xf…...

Model Context Protocol (MCP) - 尝试创建和测试一下MCP Server

1.简单介绍 MCP是Model Context Protocol的缩写&#xff0c;是Anthropic开源的一个标准协议。MCP使得大语言模型可以和外部的数据源&#xff0c;工具进行集成。当前MCP在社区逐渐地流行起来了。同时official C# SDK(仓库是csharp-sdk) 也在不断更新中&#xff0c;目前最新版本…...

Linux上位机开发实践(关于Qt的移植)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 linux平台上面&#xff0c;很多界面应用&#xff0c;都是基于qt开发的。不管是x86平台&#xff0c;还是arm平台&#xff0c;qt使用的地方都比较多。…...

Node.js 项目 用 `Docker Compose` 发布的完整流程

Node.js 项目 用 Docker Compose 发布的完整流程 ✅ 一、基本项目结构示例 以一个简单 Express 项目为例&#xff1a; my-node-app/ ├── app.js # 启动文件 ├── package.json ├── package-lock.json ├── Dockerfile # 构建 Node 容器 ├…...

Java基础:浅析Java中的XML文件处理

概述 XML&#xff08;全称Extensible Markup Language,可扩展标记语言&#xff09; .本质是一种数据的格式&#xff0c;可以用来存储复杂的数据结构&#xff0c;和数据关系 XML特点 1.XML中的“<标签名>”成为一个标签或者一个元素&#xff0c;一般成对出现的 2.XML…...

MCU刷写——S19(S-Record)文件格式详解及Python代码

工作之余来写写关于MCU的Bootloader刷写的相关知识,以免忘记。今天就来聊聊S19这种文件的格式,我是分享人M哥,目前从事车载控制器的软件开发及测试工作。 学习过程中如有任何疑问,可底下评论! 如果觉得文章内容在工作学习中有帮助到你,麻烦点赞收藏评论+关注走一波!感谢…...

HTML — 过渡与动画

HTML过渡与动画是提升网页交互体验的核心技术&#xff0c;主要通过CSS实现动态效果。 过渡 CSS过渡&#xff08;Transition&#xff09;介绍 适用于元素属性变化时的平滑渐变效果&#xff0c;如悬停变色、尺寸调整。通过定义transition-property&#xff08;过渡属性&#xf…...

python【标准库】multiprocessing

文章目录 介绍多进程Process 创建子进程共享内存数据多进程通信Pool创建子进程多进程案例多进程注意事项介绍 python3.10.17版本multiprocessing 是一个多进程标准模块,使用类似于threading模块的API创建子进程,充分利用多核CPU来并行处理任务。提供本地、远程的并发,高效避…...

BANK OF CHINA(HONG KONG)网点

BANK OF CHINA(HONG KONG)网点开户 ZoneBankAddressDates东区杏花邨分行香港柴湾杏花邨东翼商场205-208号20240415: 11:15, 13:00, 11:15, 13:00, 11:15, 13:0020240412: 11:15, 13:00东区鲗鱼涌分行香港鰂鱼涌英皇道1060号柏惠苑20240412: 09:45 注意事项 到达指定分行时&am…...

基于springboot的“嗨玩旅游网站”的设计与实现(源码+数据库+文档+PPT)

基于springboot的“嗨玩旅游网站”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;springboot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统功能结构图 局部E-R图 系统首页界面 系统注册…...

机器学习(3)——决策树

文章目录 1. 决策树基本原理1.1. 什么是决策树&#xff1f;1.2. 决策树的基本构成&#xff1a;1.3. 核心思想 2. 决策树的构建过程2.1. 特征选择2.1.1. 信息增益&#xff08;ID3&#xff09;2.1.2. 基尼不纯度&#xff08;CART&#xff09;2.1.3. 均方误差&#xff08;MSE&…...

【人脸识别中的“类内差异”和“类间差异】

核心问题&#xff1a;人脸识别中的“类内差异”和“类间差异” 想象你在教一个小朋友认人&#xff1a; 类间差异&#xff08;不同人之间的区别&#xff09;&#xff1a; 目标&#xff1a;让小朋友能分清“爸爸”和“妈妈”。方法&#xff1a;指着爸爸说“这是爸爸”&#xff0…...

第十六届蓝桥杯 省赛C/C++ 大学B组

编程题目现在在洛谷上都可以提交了。 未完待续&#xff0c;写不动了。 C11 编译命令 g A.cpp -o A -Wall -lm -stdc11A. 移动距离 本题总分&#xff1a;5 分 问题描述 小明初始在二维平面的原点&#xff0c;他想前往坐标 ( 233 , 666 ) (233, 666) (233,666)。在移动过程…...

SpringBoot3.0 +GraalVM21 + Docker 打包成可执行文件

SpringBoot3.0 GraalVM21 Docker 打包成可执行文件 前言 随着时代的飞速发展&#xff0c;JDK 17 及以上版本开始支持通过 GraalVM 将运行在 JVM 上的 jar 包直接打包成可在操作系统上运行的原生可执行文件。这一特性能使开发者在某些场景下更加灵活地部署 Java 程序。 在云原…...

从编程范式看 “万物皆智能,万事皆自动” 愿景

从编程范式看“万物皆智能,万事皆自动”愿景 引言 在信息技术飞速发展的今天,“万物皆智能,万事皆自动”成为了众多 IT 从业者和科技爱好者心中的终极愿景。这一愿景描绘了一个所有事物都具备智能、所有事情都能自动完成的美好未来。而在实现这一愿景的征程中,面向对象编…...

Vue 项目中 package.json 文件的深度解析

Vue 项目中 package.json 文件的深度解析 在 Vue 项目中&#xff0c;package.json 文件是项目配置的核心&#xff0c;它管理着项目的依赖关系、脚本命令、版本信息等重要内容。正确理解和配置 package.json 文件&#xff0c;对于项目的开发、构建、测试和部署都至关重要。本文…...

解决2080Ti使用节点ComfyUI-PuLID-Flux-Enhanced中遇到的问题

使用蓝大的工作流《一键同时换头、换脸、发型、发色之双pulid技巧》 刚开始遇到的是不支持bf16的错误 根据《bf16 is only supported on A100 GPUs #33》中提到&#xff0c;修改pulidflux.py中的dtype 为 dtype torch.float16 后&#xff0c;出现新的错误&#xff0c;这个…...

1 程序的本质,计算机语言简史,TIOBE 指数,C 语言的独特魅力、发展历程、发行版本和应用场景

&#x1f44b; 嘿&#xff0c;各位编程探险家们&#xff01;是不是一提到 C 语言&#xff0c;脑海中就浮现出指针乱舞、内存泄漏的恐怖画面&#xff1f;别怕&#xff0c;你并不孤单&#xff01;&#x1f605; 今天&#xff0c;你踏入了这个专为 “C 语言恐惧症” 患者打造的避…...

python格式化字符串漏洞

什么是python格式化字符串漏洞 python中&#xff0c;存在几种格式化字符串的方式&#xff0c;然而当我们使用的方式不正确的时候&#xff0c;即格式化的字符串能够被我们控制时&#xff0c;就会导致一些严重的问题&#xff0c;比如获取敏感信息 python常见的格式化字符串 百…...

撰写学位论文Word图表目录的自动生成

第一步&#xff1a;为图片和表格添加题注 选中图片或表格 右键点击需要编号的图片或表格&#xff0c;选择 【插入题注】&#xff08;或通过菜单栏 引用 → 插入题注&#xff09;。 设置题注标签 在弹窗中选择 标签&#xff08;如默认有“图”“表”&#xff0c;若无需自定义标…...

SDC命令详解:使用相对路径访问设计对象(current_instance命令)

相关阅读 SDC命令详解https://blog.csdn.net/weixin_45791458/category_12931432.html?spm1001.2014.3001.5482 在使用get_cells等命令访问设计对象时&#xff0c;需要指定设计对象的名字&#xff0c;这个名字是一个相对路径&#xff0c;本文就将对此进行讨论。 相对路径 使…...

vector的应用

在平常使用c是&#xff0c;只使用普通数组肯定不够便捷&#xff0c;这时&#xff0c;我们就可以使用vector来使代码更加简洁 目录 1.vector的定义 2.在vector末尾增加一个元素 3.输出元素 &#xff08;1&#xff09;输出单个元素 &#xff08;2&#xff09;循环输出元素 4…...

pytorch查询字典、列表维度

输出tensor变量维度 print(a.shape)输出字典维度 for key, value in output_dict.items():if isinstance(value, torch.Tensor):print(f"{key} shape:", value.shape)输出列表维度 def get_list_dimensions(lst):# 基线条件&#xff1a;如果lst不是列表&#xff0…...

征程 6 VIO Frame 时间戳介绍

1. 时间类型 征程 6 内部的时间类型如下 Linux 系统时间是基于 arm system counter 抽象的&#xff0c;Linux 的基于 arm system counter 抽象了很多种时间&#xff0c;图中画了两种。CLOCK_MONOTONIC_RAW 是不会被时间同步调整的。 2. Frame 时间戳 从 VIO 侧获取的图像数…...

DotnetCore开源库SampleAdmin源码编译

1.报错: System.Net.Sockets.SocketException HResult0x80004005 Message由于目标计算机积极拒绝&#xff0c;无法连接。 SourceSystem.Net.Sockets StackTrace: 在 System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, C…...

QML之ScrollView(滚动视图)

ScrollView 是 Qt Quick Controls 2 中提供的可滚动视图容器&#xff0c;用于创建可滚动区域。以下是详细使用方法&#xff1a; 基本用法 qml import QtQuick 2.15 import QtQuick.Controls 2.15ScrollView {id: scrollViewwidth: 300height: 200clip: true// 背景设置&…...