当前位置:首页 > 生态圈 > 正文内容

java的基础知识面试题及答案(java面试知识点汇总)

abcsky883个月前 (02-10)生态圈69

本文分享给大家的是:

原文地址:https://mp.weixin.qq.com/s/PQA_sB5J2nK05ilKUDz0mQ侵权联系删除面向对象基础面向对象和面向过程的区别两者的主要区别在于解决问题的方式不同:面向过程把解决问题的过程拆成一个个方法,通过一个个方法的执行解决问题。

java的基础知识面试题及答案(java面试知识点汇总)

面向对象会先抽象出对象,然后用对象执行方法的方式解决问题另外,面向对象开发的程序一般更易维护、易复用、易扩展相关 issue : 面向过程 :面向过程性能比面向对象高??成员变量与局部变量的区别语法形式。

:从语法形式上看,成员变量是属于类的,而局部变量是在代码块或方法中定义的变量或是方法的参数;成员变量可以被 pu网站建设营销推广blic,private,static 等修饰符所修饰,而局部变量不能被访问控制修饰符及

static 所修饰;但是,成员变量和局部变量都能被 final 所修饰存储方式 :从变量在内存中的存储方式来看,如果成员变量是使用 static 修饰的,那么这个成员变量是属于类的,如果没有使用 static

修饰,这个成员变量是属于实例的而对象存在于堆内存,局部变量则存在于栈内存生存时间 :从变量在内存中的生存时间上看,成员变量是对象的一部分,它随着对象的创建而存在,而局部变量随着方法的调用而自动生成,随着方法的调用结束而消亡。

默认值 :从变量是否有默认值来看,成员变量如果没有被赋初始值,则会自动以类型的网站建设营销推广默认值而赋值(一种情况例外:被 final 修饰的成员变量也必须显式地赋值),而局部变量则不会自动赋值创建一个对象用什么运算符?对象实体与对象引用有何不同?。

new 运算符,new 创建对象实例(对象实例在堆内存中),对象引用指向对象实例(对象引用存放在栈内存中)一个对象引用可以指向 0 个或 1 个对象(一根绳子可以不系气球,也可以系一个气球);一个对象可以有 n 个引用指向它(可以用 n 条绳子系住一个气球)。

对象的相等和引用相等的区别对象的相等一般比较的是内存中存放的内容是否相等引用相等一般比较的是他们指向的内存地址是否相等类的构造方法的作用是什么?构造方法是一种特殊的方法,主要作用是完网站建设营销推广成对象的初始化工作如果一个类没有声明构造方法,该程序能正确执行吗?

如果一个类没有声明构造方法,也可以执行!因为一个类即使没有声明构造方法也会有默认的不带参数的构造方法如果我们自己添加了类的构造方法(无论是否有参),Java 就不会再添加默认的无参数的构造方法了,我们一直在不知不觉地使用构造方法,这也是为什么我们在创建对象的时候后面要加一个括号(因为要调用无参的构造方法)。

如果我们重载了有参的构造方法,记得都要把无参的构造方法也写出来(无论是否用到),因为这可以帮助我们在创建对象的时候少踩坑构造方法有哪些特点?是否可被 override?构造方法特点如下:名字与类名相同没有返回值,但不能用 vo网站建设营销推广id 声明构造函数。

生成类的对象时自动执行,无需调用构造方法不能被 override(重写),但是可以 overload(重载),所以你可以看到一个类中有多个构造函数的情况面向对象三大特征封装封装是指把一个对象的状态信息(也就是属性)隐藏在对象内部,不允许外部对象直接访问对象的内部信息。

但是可以提供一些可以被外界访问的方法来操作属性就好像我们看不到挂在墙上的空调的内部的零件信息(也就是属性),但是可以通过遥控器(方法)来控制空调如果属性不想被外界访问,我们大可不必提供方法给外界访问但是如果一个类没有提供给外界访问的方法,那么这个类也没有什么意义了。

就好像如果没有空调遥控器,那么我们就无法操控空网站建设营销推广凋制冷,空调本身就没有意义了(当然现在还有很多其他方法 ,这里只是为了举例子)publicclassStudent {privateint id;//id属性私有化

private String name;//name属性私有化//获取id的方法publicintgetId(){ return id; } //设置id的方法public

voidsetId(int id){ this.id = id; } //获取name的方法public String getName(){ ret网站建设营销推广urn

name; } //设置name的方法publicvoidsetName(String name){ this.name = name; } } 继承不同类型的对象,相互之间经常有一定数量的共同点。

例如,小明同学、小红同学、小李同学,都共享学生的特性(班级、学号等)同时,每一个对象还定义了额外的特性使得他们与众不同例如小明的数学比较好,小红的性格惹人喜爱;小李的力气比较大继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地网站建设营销推广继承父类。

通过使用继承,可以快速地创建新的类,可以提高代码的重用,程序的可维护性,节省大量创建新类的时间 ,提高我们的开发效率关于继承如下 3 点请记住:子类拥有父类对象所有的属性和方法(包括私有属性和私有方法),但是父类中的私有属性和方法子类是无法访问,

只是拥有子类可以拥有自己属性和方法,即子类可以对父类进行扩展子类可以用自己的方式实现父类的方法(以后介绍)多态多态,顾名思义,表示一个对象具有多种的状态,具体表现为父类的引用指向子类的实例多态的特点:对象类型和引用类型之间具有继承(类)/实现(接口)的关系;

引用类型变量发出的方法调用的到底是哪个类中的方法,必须在程序运行期间才能确定;多态不能网站建设营销推广调用“只在子类存在但在父类不存在”的方法;如果子类重写了父类的方法,真正执行的是子类覆盖的方法,如果子类没有覆盖父类的方法,执行的是父类的方法。

接口和抽象类有什么共同点和区别?共同点 :都不能被实例化都可以包含抽象方法都可以有默认实现的方法(Java 8 可以用 default 关键字在接口中定义默认方法)区别 :接口主要用于对类的行为进行约束,你实现了某个接口就具有了对应的行为。

抽象类主要用于代码复用,强调的是所属关系(比如说我们抽象了一个发送短信的抽象类,)一个类只能继承一个类,但是可以实现多个接口接口中的成员变量只能是 public static final 类型的,不能被修改且必须有初网站建设营销推广始值,而抽象类的成员变量默认 default,可在子类中被重新定义,也可被重新赋值。

深拷贝和浅拷贝区别了解吗?什么是引用拷贝?关于深拷贝和浅拷贝区别,我这里先给结论:浅拷贝:浅拷贝会在堆上创建一个新的对象(区别于引用拷贝的一点),不过,如果原对象内部的属性是引用类型的话,浅拷贝会直接复制内部对象的引用地址,也就是说拷贝对象和原对象共用同一个内部对象。

深拷贝 :深拷贝会完全复制整个对象,包括这个对象所包含的内部对象上面的结论没有完全理解的话也没关系,我们来看一个具体的案例!浅拷贝浅拷贝的示例代码如下,我们这里实现了 Cloneable 接口,并重写了 。

clone() 方法clone() 方法的网站建设营销推广实现很简单,直接调用的是父类 Object 的 clone() 方法publicclassAddressimplementsCloneable{ private

String name; // 省略构造函数、Getter&Setter方法@Overridepublic Address clone(){ try {

return (Address) super.clone(); } catch (CloneNotSupportedException e) { thrownew

AssertionError(); 网站建设营销推广 } } } publicclassPersonimplementsCloneable{ private Address address;

// 省略构造函数、Getter&Setter方法@Overridepublic Person clone(){ try { Person person = (Person)

super.clone(); return person; } catch (CloneNotSupportedException e) {

throwne网站建设营销推广w AssertionError(); } } } 测试 :Person person1 = new Person(new Address("武汉")); Person person1Copy = person1.clone();

// true System.out.println(person1.getAddress() == person1Copy.getAddress()); 从输出结构就可以看出, person1 的克隆对象和

person1 使用的仍然是同一个 Address网站建设营销推广 对象深拷贝这里我们简单对 Person 类的 clone() 方法进行修改,连带着要把 Person 对象内部的 Address 对象一起复制@Override。

public Person clone(){ try { Person person = (Person) super.clone(); person.setAddress(person.getAddress().clone());

return person; } catch (CloneNotSupportedException e) { thrown网站建设营销推广ew AssertionError(); } }

测试 :Person person1 = new Person(new Address("武汉")); Person person1Copy = person1.clone(); // false System.

out.println(person1.getAddress() == person1Copy.getAddress()); 从输出结构就可以看出,虽然 person1 的克隆对象和 person1 包含的

Address 对象已经是不同的了。那网站建设营销推广什么是引用拷贝呢? 简单来说,引用拷贝就是两个不同的引用指向同一个对象。我专门画了一张图来描述浅拷贝、深拷贝、引用拷贝:

Java 常见类ObjectObject 类的常见方法有哪些?Object 类是一个特殊的类,是所有类的父类它主要提供了以下 11 个方法:/** * native 方法,用于返回当前运行时对象的 Class 对象,使用了 final 关键字修饰,故不允许子类重写。

*/publicfinalnative Class getClass() /** * native 方法,用于返回对象的哈希码,主要使用在哈希表中,比如 JDK 中的网站建设营销推广HashMap */public

nativeinthashCode()/** * 用于比较 2 个对象的内存地址是否相等,String 类对该方法进行了重写以用于比较字符串的值是否相等 */publicbooleanequals(Object obj)

/** * naitive 方法,用于创建并返回当前对象的一份拷贝 */protectednative Object clone()throws CloneNotSupportedException 。

/** * 返回类的名字实例的哈希网站建设营销推广码的 16 进制的字符串建议 Object 所有的子类都重写这个方法 */public String toString()/** * native 方法,并且不能重写。

唤醒一个在此对象监视器上等待的线程(监视器相当于就是锁的概念)如果有多个线程在等待只会任意唤醒一个 */publicfinalnativevoidnotify()/** * native 方法,并且不能重写。

跟 notify 一样,唯一的区别就是会唤醒在此对象监视器上等待的所有线程,而不是一个线程 */publicfinalnativevoidnot网站建设营销推广ifyAll()/** * native方法,并且不能重写。

暂停线程的执行注意:sleep 方法没有释放锁,而 wait 方法释放了锁 ,timeout 是等待时间 */publicfinalnativevoidwait(long timeout)throws

InterruptedException /** * 多了 nanos 参数,这个参数表示额外时间(以毫微秒为单位,范围是 0-999999) 所以超时的时间还需要加上 nanos 毫秒 */public

finalvoidwait(long timeout, 网站建设营销推广int nanos)throws InterruptedException /** * 跟之前的2个wait方法一样,只不过该方法一直等待,没有超时时间这个概念 */

publicfinalvoidwait()throws InterruptedException /** * 实例被垃圾回收器回收的时候触发的操作 */protectedvoidfinalize()

throws Throwable { } == 和 equals() 的区别== 对于基本类型和引用类型的作用效果是不同的:网站建设营销推广对于基本数据类型来说,== 比较的是值对于引用数据类型来说,== 比较的是对象的内存地址。

因为 Java 只有值传递,所以,对于 == 来说,不管是比较基本数据类型,还是引用数据类型的变量,其本质比较的都是值,只是引用类型变量存的值是对象的地址equals() 不能用于判断基本数据类型的变量,只能用来判断两个对象是否相等。

equals()方法存在于Object类中,而Object类是所有类的直接或间接父类,因此所有的类都有equals()方法Object 类 equals() 方法:publicbooleanequals。

(Object obj){ return (this =网站建设营销推广= obj); } equals() 方法存在两种使用情况:类没有重写 equals()方法 :通过equals()比较该类的两个对象时,等价于通过“==”比较这两个对象,使用的默认是

Object类equals()方法类重写了 equals()方法 :一般我们都重写 equals()方法来比较两个对象中的属性是否相等;若它们的属性相等,则返回 true(即,认为这两个对象相等)举个例子(这里只是为了举例。

实际上,你按照下面这种写法的话,像 IDEA 这种比较智能的 IDE 都会提示你将 == 换成 equals() ):String a = newString(网站建设营销推广"ab"); // a 为一个引用String

b = newString("ab"); // b为另一个引用,对象的内容一样String aa = "ab"; // 放在常量池中String bb = "ab"; // 从常量池中查找 System.out.println(aa == bb);

// true System.out.println(a == b);// false System.out.println(a.equals(b));// true System.out.println(

42 == 42.0);// tru网站建设营销推广eString 中的 equals 方法是被重写过的,因为 Object 的 equals 方法是比较的对象的内存地址,而 String 的 equals 方法比较的是对象的值。

当创建 String 类型的对象时,虚拟机会在常量池中查找有没有已经存在的值和要创建的值相同的对象,如果有就把它赋给当前引用如果没有就在常量池中重新创建一个 String 对象String类equals()。

方法:public boolean equals(Object anObject) { if (this == anObject) { returntrue; }

if网站建设营销推广 (anObject instanceof String) { String anotherString = (String)anObject; int n = value

.length; if (n == anotherString.value.length) { char v1[] = value; char

v2[] = anotherString.value; int i = 0; while (n-- != 0) { if

(v1[i] != v2[i]) 网站建设营销推广 returnfalse; i++; } return

true; } } returnfalse; } hashCode() 有什么用?hashCode() 的作用是获取哈希码(int 整数),也称为散列码这个哈希码的作用是确定该对象在哈希表中的索引位置。

hashCode()定义在 JDK 的 Object 类中,这就意味着 Java 中的任何类都包含有 hashCode() 函数另外需要注意的是:Object 的 hashCode() 方法是本地方法,也就网站建设营销推广是用 C 语言或 C++ 实现的,该方法通常用来将对象的内存地址转换为整数之后返回。

publicnativeinthashCode(); 散列表存储的是键值对(key-value),它的特点是:能根据“键”快速的检索出对应的“值”这其中就利用到了散列码!(可以快速找到所需要的对象)为什么要有 hashCode?

我们以“HashSet 如何检查重复”为例子来说明为什么要有 hashCode?下面这段内容摘自我的 Java 启蒙书《Head First Java》:当你把对象加入 HashSet 时,HashSet

会先计算对象的 hashCode 值来判断对象加入的位置,同时也会与网站建设营销推广其他已经加入的对象的 hashCode 值作比较,如果没有相符的 hashCode,HashSet 会假设对象没有重复出现但是如果发现有相同 。

hashCode 值的对象,这时会调用 equals() 方法来检查 hashCode 相等的对象是否真的相同如果两者相同,HashSet 就不会让其加入操作成功如果不同的话,就会重新散列到其他位置这样我们就大大减少了 。

equals 的次数,相应就大大提高了执行速度其实, hashCode() 和 equals()都是用于比较两个对象是否相等那为什么 JDK 还要同时提供这两个方法呢?这是因为在一些容器(比如 HashMap。

、HashSet)中,有网站建设营销推广了 hashCode() 之后,判断元素是否在对应容器中的效率会更高(参考添加元素进HashSet的过程)!我们在前面也提到了添加元素进HashSet的过程,如果 HashSet

在对比的时候,同样的 hashCode 有多个对象,它会继续使用 equals() 来判断是否真的相同也就是说hashCode 帮助我们大大缩小了查找成本那为什么不只提供 hashCode() 方法呢?。

这是因为两个对象的hashCode 值相等并不代表两个对象就相等那为什么两个对象有相同的 hashCode 值,它们也不一定是相等的?因为 hashCode() 所使用的哈希算法也许刚好会让多个对象传回相同的哈希值。

网站建设营销推广糟糕的哈希算法越容易碰撞,但这也与数据值域分布的特性有关(所谓哈希碰撞也就是指的是不同的对象得到相同的 hashCode )总结下来就是 :如果两个对象的hashCode 值相等,那这两个对象不一定相等(哈希碰撞)。

如果两个对象的hashCode 值相等并且equals()方法也返回 true,我们才认为这两个对象相等如果两个对象的hashCode 值不相等,我们就可以直接认为这两个对象不相等相信大家看了我前面对 。

hashCode() 和 equals() 的介绍之后,下面这个问题已经难不倒你们了为什么重写 equals() 时必须重写 hashCode() 方法?因为两个相等的对象的 ha网站建设营销推广shCode 值必须是相等。

也就是说如果 equals 方法判断两个对象是相等的,那这两个对象的 hashCode 值也要相等如果重写 equals() 时没有重写 hashCode() 方法的话就可能会导致 equals 方法判断是相等的两个对象,。

hashCode 值却不相等思考 :重写 equals() 时没有重写 hashCode() 方法的话,使用 HashMap 可能会出现什么问题总结 :equals 方法判断两个对象是相等的,那这两个对象的 。

hashCode 值也要相等两个对象有相同的 hashCode 值,他们也不一定是相等的(哈希碰撞)更多关于 hashCode() 和 e网站建设营销推广quals() 的内容可以查看:Java hashCode() 和 equals()的若干问题解答。

StringString、StringBuffer、StringBuilder 的区别?可变性String 是不可变的(后面会详细分析原因)StringBuilder 与 StringBuffer 都继承自 。

AbstractStringBuilder 类,在 AbstractStringBuilder 中也是使用字符数组保存字符串,不过没有使用 final 和 private 关键字修饰,最关键的是这个 AbstractStringBuilder

类还提供了很多修改字符串的方法比如 append网站建设营销推广 方法abstractclassAbstractStringBuilderimplementsAppendable, CharSequence { 。

char[] value; public AbstractStringBuilder append(String str) { if (str == null)

return appendNull(); int len = str.length(); ensureCapacityInternal(count + len); str.getChars(

0,网站建设营销推广 len, value, count); count += len; returnthis; } //... } 线程安全性String 中的对象是不可变的,也就可以理解为常量,线程安全。

AbstractStringBuilder 是 StringBuilder 与 StringBuffer 的公共父类,定义了一些字符串的基本操作,如 expandCapacity、append、insert

、indexOf 等公共方法StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安网站建设营销推广全的StringBuilder并没有对方法进行加同步锁,所以是非线程安全的性能每次对 String

类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象StringBuffer 每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。

相同情况下使用 StringBuilder 相比使用StringBuffer 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险对于三者使用的总结:操作少量的数据: 适用 String。

单线程操作字符串缓冲区下操作大量数据: 适用 StringBuilder多线程操作字符网站建设营销推广串缓冲区下操作大量数据: 适用 StringBufferString 为什么是不可变的?String 类中使用 final

关键字修饰字符数组来保存字符串,所以String 对象是不可变的publicfinalclassStringimplementsjava.io.Serializable, Comparable

>, CharSequence{ privatefinalchar value[]; //... } 修正 :我们知道被 final 关键字修饰的类不能被继承,修饰的方法不能被重写,修饰的变量是基本数据类型则值不能改变,修网站建设营销推广饰的变量是引用类型则不能再指向其他对象。

因此,final 关键字修饰的数组保存字符串并不是 String 不可变的根本原因,因为这个数组保存的字符串是可变的(final 修饰引用类型变量的情况)String 真正不可变有下面几点原因:保存字符串的数组被 。

final 修饰且为私有的,并且String 类没有提供/暴露修改这个字符串的方法String 类被 final 修饰导致其不能被继承,进而避免了子类破坏 String 不可变相关阅读:如何理解 String 类型值的不可变?- 知乎提问。

补充(来自issue 675):在 Java 9 之后,String 、StringBuilder 与 网站建设营销推广StringBuffer 的实现改用 byte 数组存储字符串publicfinalclassString

implementsjava.io.Serializable,Comparable, CharSequence {// @Stable 注解表示变量最多被修改一次,称为“稳定的”@Stable。

privatefinalbyte[] value;}abstractclassAbstractStringBuilderimplementsAppendable, CharSequence {byte[] value;

}Java 9 为何要将 String 的底层实现由 char[] 改成了 byt网站建设营销推广e[] ?新版的 String 其实支持两个编码方案:Latin-1 和 UTF-16如果字符串中包含的汉字没有超过 Latin-1 可表示范围内的字符,那就会使用 Latin-1 作为编码方案。

Latin-1 编码方案下,byte 占一个字节(8 位),char 占用 2 个字节(16),byte 相较 char 节省一半的内存空间JDK 官方就说了绝大部分字符串对象只包含 Latin-1 可表示的字符。

如果字符串中包含的汉字超过 Latin-1 可表示范围内的字符,byte 和 char 所占用的空间是一样的这是官方的介绍:https://openjdk.java.net/jeps/254网站建设营销推广 字符串拼接用“+” 还是 StringBuilder?。

Java 语言本身并不支持运算符重载,“+”和“+=”是专门为 String 类重载过的运算符,也是 Java 中仅有的两个重载过的元素符String str1 = "he"; String str2 = 。

"llo"; String str3 = "world"; String str4 = str1 + str2 + str3; 上面的代码对应的字节码如下:

可以看出,字符串对象通过“+”的字符串拼接方式,实际上是通过 StringBuilder 调用 append() 网站建设营销推广方法实现的,拼接完成之后调用 toString() 得到一个 String 对象 不过,在循环内使用“+”进行字符串的拼接的话,存在比较明显的缺陷:。

编译器不会创建单个 StringBuilder 以复用,会导致创建过多的 StringBuilder 对象String[] arr = {"he", "llo", "world"}; String s = 。

""; for (int i = 0; i < arr.length; i++) { s += arr[i]; } System.out.println(s); 网站建设营销推广 StringBuilder 对象是在循环内部被创建的,这意味着每循环一次就会创建一个

StringBuilder 对象。

如果直接使用 StringBuilder 对象进行字符串拼接的话,就不会存在这个问题了String[] arr = {"he", "llo", "world"}; StringBuilder s = new

StringBuilder(); for (String value : arr) { s.append(value); } System.out.println(s);

如果你使用网站建设营销推广 IDEA 的话,IDEA 自带的代码检查机制也会提示你修改代码String#equals() 和 Object#equals() 有何区别?String 中的 equals 方法是被重写过的,比较的是 String 字符串的值是否相等。

Object 的 equals 方法是比较的对象的内存地址字符串常量池的作用了解吗?字符串常量池 是 JVM 为了提升性能和减少内存消耗针对字符串(String 类)专门开辟的一块区域,主要目的是为了避免字符串的重复创建。

// 在堆中创建字符串对象”ab“// 将字符串对象”ab“的引用保存在字符串常量池中String aa = "ab"; /网站建设营销推广/ 直接返回字符串常量池中字符串对象”ab“的引用String bb = "ab"

; System.out.println(aa==bb);// true更多关于字符串常量池的介绍可以看一下 Java 内存区域详解 这篇文章String s1 = new String("abc");这句话创建了几个字符串对象?。

会创建 1 或 2 个字符串对象1、如果字符串常量池中不存在字符串对象“abc”的引用,那么会在堆中创建 2 个字符串对象“abc”示例代码(JDK 1.8):String s1 = newString。

("abc"); 对应的字节码:

ldc 命令用于判网站建设营销推广断字符串常量池中是否保存了对应的字符串对象的引用,如果保存了的话直接返回,如果没有保存的话,会在堆中创建对应的字符串对象并将该字符串对象的引用保存到字符串常量池中2、如果字符串常量池中已存在字符串对象“abc”的引用,则只会在堆中创建 1 个字符串对象“abc”。

示例代码(JDK 1.8):// 字符串常量池中已存在字符串对象“abc”的引用String s1 = "abc"; // 下面这段代码只会在堆中创建 1 个字符串对象“abc”String s2 =

newString("abc"); 对应的字节码:

这里就不对上面的字节码进行详细注释了,7 这个位置的 网站建设营销推广ldc 命令不会在堆中创建新的字符串对象“abc”,这是因为 0 这个位置已经执行了一次 ldc 命令,已经在堆中创建过一次字符串对象“abc”了7 这个位置执行 。

ldc 命令会直接返回字符串常量池中字符串对象“abc”对应的引用intern 方法有什么作用?String.intern() 是一个 native(本地)方法,其作用是将指定的字符串对象的引用保存在字符串常量池中,可以简单分为两种情况:。

如果字符串常量池中保存了对应的字符串对象的引用,就直接返回该引用如果字符串常量池中没有保存了对应的字符串对象的引用,那就在常量池中创建一个指向该字符串对象的引用并返回示例代码(JDK 1.8) 网站建设营销推广:// 在堆中创建字符串对象”Java“

// 将字符串对象”Java“的引用保存在字符串常量池中String s1 = "Java"; // 直接返回字符串常量池中字符串对象”Java“对应的引用String s2 = s1.intern();

// 会在堆中在单独创建一个字符串对象String s3 = newString("Java"); // 直接返回字符串常量池中字符串对象”Java“对应的引用String s4 = s3.intern();

// s1 和 s2 指向的是堆中的同一个对象 System.out.println(s1 == s网站建设营销推广2); // true// s3 和 s4 指向的是堆中不同的对象 System.out.println(s3 == s4);

// false// s1 和 s4 指向的是堆中的同一个对象 System.out.println(s1 == s4); //trueString 类型的变量和常量做“+”运算时发生了什么?先来看字符串不加

final 关键字拼接的情况(JDK1.8):String str1 = "str"; String str2 = "ing"; String str3 = "str" + "ing"; 网站建设营销推广 String str4 = str1 + str2;

String str5 = "string"; System.out.println(str3 == str4);//false System.out.println(str3 == str5);//true

System.out.println(str4 == str5);//false注意 :比较 String 字符串的值是否相等,可以使用 equals() 方法String 中的 equals 方法是被重写过的。

Object 的 equals 方法是比较的对象的内存地址,而 String 的 equals网站建设营销推广 方法比较的是字符串的值是否相等如果你使用 == 比较两个字符串是否相等的话,IDEA 还是提示你使用 equals()

方法替换。

对于编译期可以确定值的字符串,也就是常量字符串 ,jvm 会将其存入字符串常量池并且,字符串常量拼接得到的字符串常量在编译阶段就已经被存放字符串常量池,这个得益于编译器的优化在编译过程中,Javac 编译器(下文中统称为编译器)会进行一个叫做 。

常量折叠(Constant Folding) 的代码优化。《深入理解 Java 虚拟机》中是也有介绍到:

常量折叠会把常量表达式的值求出来作为常量嵌在最终生成的代码中,这是 Javac 编译器会对源代码做的极少量优化措施之一(网站建设营销推广代码优化几乎都在即时编译器中进行)对于 String str3 = "str" + "ing";。

编译器会给你优化成 String str3 = "string";并不是所有的常量都会进行折叠,只有编译器在程序编译期就可以确定值的常量才可以:基本数据类型( byte、boolean、short、char

、int、float、long、double)以及字符串常量final 修饰的基本数据类型和字符串变量字符串通过 “+”拼接得到的字符串、基本数据类型之间算数运算(加减乘除)、基本数据类型的位运算(<>、>>> )。

引用的值在程序编译期是无法确定的,编译器无法对其进行优化对象引用和“+”的字符串网站建设营销推广拼接方式,实际上是通过 StringBuilder 调用 append() 方法实现的,拼接完成之后调用 toString()。

得到一个 String 对象 String str4 = new StringBuilder().append(str1).append(str2).toString(); 我们在平时写代码的时候,尽量避免多个字符串对象拼接,因为这样会重新创建对象。

如果需要改变字符串的话,可以使用 StringBuilder 或者 StringBuffer不过,字符串使用 final 关键字声明之后,可以让编译器当做常量来处理示例代码:finalString str1网站建设营销推广 =

"str"; finalString str2 = "ing"; // 下面两个表达式其实是等价的String c = "str" + "ing";// 常量池中的对象String d = str1 + str2;

// 常量池中的对象 System.out.println(c == d);// true被 final 关键字修改之后的 String 会被编译器当做常量来处理,编译器在程序编译期就可以确定它的值,其效果就相当于访问常量。

如果 ,编译器在运行时才能知道其确切值的话,就无法对其优化示例代码(str2 在运行时才能确定其值):fina网站建设营销推广lString str1 = "str"; finalString str2 = getStr(); 。

String c = "str" + "ing";// 常量池中的对象String d = str1 + str2; // 在堆上创建的新的对象 System.out.println(c == d);// false

public staticString getStr() { return"ing"; }

扫描二维码推送至手机访问。

版权声明:本文由海南拓宏网络科技工作室发布,如需转载请注明出处。

本文链接:http://4blc.com/post/16103.html

分享给朋友:

“java的基础知识面试题及答案(java面试知识点汇总)” 的相关文章

零基础可以自学java吗知乎(零基础可以自学java吗女生)

本文分享给大家的是: 原标题:零基础自学java需要注意什么零基础自学java需要注意什么?如果要自学Java技术的话,实话说,光依靠Java视频教程并不是一个明智的选择我们可以以视频教程为我们的主力学习工具,辅助书籍来加深我们对Java技术的深入理解。 现如今随着IT行业...

java语言概述笔记(java语言简述)

本文分享给大家的是: JAVA语言概述一、初识JAVA什么是计算机语言?语言:是人与人之间用于沟通的一种方式例如:中国人与中国人用中文沟通,而中国人要和韩国人交流,就要学习韩语计算机语言:人与计算机交流的方式如果人要与计算机交流,那么就要学习计算机语言,计算机语言有很众多,如:C,...

java下载官网(java下载手机版)

本篇文章给大家谈谈 阿里极客公益活动:或许你挑灯夜战只为一道难题或许你百思不解只求一个答案或许你绞尽脑汁只因一种未知那么他们来了,阿里系技术专家来云栖问答为你解答技术难题了!本次活动特邀百位阿里技术专家对Java常见问题进行了集中解答,在短短3天时间专家回答了1460道Java问题...

java的基本介绍(java的介绍)

本文分享给大家的是: 1.java语言背景介绍(了解)语言:人与人交流沟通的表达方式计算机语言:人与计算机之间进行信息交流沟通的一种特殊语言Java语言是美国Sun公司(Stanford University Network)在 1995年推出的计算机语言Java之父:詹姆...

华为hms有多少应用了(华为hms发展最新消息)

本篇文章给大家谈谈 腾讯科技讯 北京时间2月24日,华为消费者业务在巴塞罗那举行主题为“共联未来”的终端产品与战略线上发布会,除发布多款5G全场景智慧终端新品外,并介绍了华为应用市场及HMS生态构筑最新进展应用市场华为首先介绍了应用市场的最新进展,作为全球前三大应用市场之一,华为应...

法国海军战舰的名称(法国海军舰艇命名规则)

本篇文章给大家谈谈 原标题:剑指双航母,法国海军也有雄心壮志,议员和将军坦承:计划不现实考虑到双航母,法国海军的野心也很大士兵和将军承认这个计划不切实际整个国家的殖民体系土崩瓦解,军力大减在这种情况下,他们根本无力维持一支庞大的海军。 今天的英法两国可谓亲如兄弟。虽然英国皇...