2.Java基础、面向对象高频面试题

目录


Java Web面试题目录清单(高频面试题型)(点击进入…)


Java基础、面向对象高频面试题


Java基础、面向对象高频面试题

1.何为编程?

编程就是让计算机为解决某个问题而使用某种程序设计语言编写程序代码,并最终得到结果的过程。

为了使计算机能够理解人的意图,人类就必须要将需解决的问题的思路、方法、和手段通过计算机能够理解的形式告诉计算机,使得计算机能够根据人的指令一步一步去工作,完成某种特定的任务。这种人和计算机之间交流的过程就是编程


2.什么是Java?

Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程


3.JDK 1.5之后的三大版本

Java SE(J2SE,Java 2 Platform Standard Edition,标准版)
Java SE以前称为J2SE。允许开发和部署在桌面、服务器、嵌入式环境和实时环境中使用的Java应用程序。Java SE包含了支持Java Web服务开发的类,并为Java EE和Java ME提供基础

Java EE(J2EE,Java 2 Platform Enterprise Edition,企业版)
Java EE以前称为J2EE。企业版本帮助开发和部署可移植、健壮、可伸缩且安全的服务器端Java 应用程序。Java EE是在Java SE的基础上构建的,它提供Web服务、组件模型、管理和通信API,可以用来实现企业级的面向服务体系结构(service-oriented architecture,SOA)和Web 2.0应用程序。2018年2月,Eclipse宣布正式将JavaEE更名为JakartaEE

Java ME(J2ME,Java 2 Platform Micro Edition,微型版)
Java ME以前称为J2ME。Java ME为在移动设备和嵌入式设备(比如手机、PDA、电视机顶盒和打印机)上运行的应用程序提供一个健壮且灵活的环境。Java ME 包括灵活的用户界面、健壮的安全模型、许多内置的网络协议以及对可以动态下载的连网和离线应用程序的丰富支持。基于 Java ME 规范的应用程序只需编写一次,就可以用于许多设备,而且可以利用每个设备的本机功能


4.JVM、JRE和JDK关系

JVM
Java Virtual Machine是Java虚拟机,Java程序需要运行在虚拟机上,不同的平台有自己的虚拟机,因此Java语言可以实现跨平台

JRE
Java Runtime Environment是Java运行环境,包括Java虚拟机和Java程序所需的核心类库等
核心类库主要是java.lang包:包含了运行Java程序必不可少的系统类,如基本数据类型、基本数学函数、字符串处理、线程、异常处理类(系统缺省加载这个包)
如果运行一个开发好的Java程序,计算机中只需要安装JRE即可

JDK
Java Development Kit是提供给Java开发人员使用的,其中包含Java开发工具、JRE。所以安装了JDK,就无需再单独安装JRE了。其中开发工具:编译工具(javac.exe)、打包工具(jar.exe)等


5.什么是跨平台性?

所谓跨平台性:指Java语言编写的程序,一次编译后,可以在多个系统平台上运行

实现原理:Java程序是通过Java虚拟机在系统平台上运行的,只要该系统可以安装相应的Java虚拟机,该系统就可以运行Java程序


6.Java语言有哪些特点(优点)?

1.简单易学(Java语言的语法与C语言和C++语言很接近)
2.面向对象(封装、继承、多态)
3.平台无关性(Java虚拟机实现平台无关性)
4.支持网络编程并且很方便(Java语言诞生本身就是为简化网络编程设计的)
5.支持多线程(多线程机制使应用程序在同一时间并行执行多项任)
6.健壮性(Java语言的强类型机制、异常处理、垃圾的自动收集等)
7. 安全性


7.Java缺点

(1)跨平台性
虽然是很好的优势,可以让Java在任何的系统中运行,但是前提是该系统要安装Java虚拟机,这样导致一些Java编写的桌面程序无法在一般的用户(没有安装Java虚拟机的用户)上使用。Java的运行速度是用class常驻内存来完成的,所以它在一些情况下所使用的内存比起用户数量来说确实是“最低性能价格比”了。从另一方面,它还需要硬盘空间来储存一系列的。.java文件和.class文件,以及对应的版本文件

(2)兼容性差
Java的身后是SUN --> Oracle公司,提供及时的API更新,但是过多的版本导致Java的向下兼容性很差。而SUN公司在J2EE上的标准定义的并不是完美,导致在J2EE的开发中多数使用开源框架,开源框架是好东西,但是更新速度并不快

(3)面向对象
都说面向对象的语言先进与面向过程,Java是OOP语言,但是它适合的是BS系统,在WEB项目中Java的实力毋庸置疑,但是转到了底层的程序却无法同C++抗衡

(4)开源导致框架架构多
个人认为Java的最大优点是开源,但是这往往也成了最大的缺陷了,无法定义一个好的标准使得开发时使用了框架,在新的程序员来到公司时必须先了解框架,延缓了开发的时间


8.什么是class字节码?采用字节码的最大好处是什么?

**字节码:**Java源代码经过虚拟机编译器编译后产生的文件(即扩展为.class的文件),它不面向任何特定的处理器,只面向虚拟机


9.采用字节码的好处?

Java语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。所以Java程序运行时比较高效,而且,由于字节码并不专对一种特定的机器,只需要虚拟机解析丢给电脑即可。因此,Java程序无须重新编译便可在多种不同的计算机上运行

Java中的编译器、解释器
Java中引入了虚拟机的概念,即在机器和编译程序之间加入了一层抽象的虚拟机器。虚拟机在任何平台上都提供给编译程序一个的共同的接口。编译程序只需要面向虚拟机,生成虚拟机能够理解的代码,然后由解释器来将虚拟机代码转换为特定系统的机器码执行

在Java中,这种供虚拟机理解的代码叫做字节码(即扩展为.class的文件),它不面向任何特定的处理器,只面向虚拟机。每一种平台的解释器是不同的,但是实现的虚拟机是相同的。Java源程序经过编译器编译后变成字节码,字节码由虚拟机解释执行,虚拟机将每一条要执行的字节码送给解释器,解释器将其翻译成特定机器上的机器码,然后在特定的机器上运行,这就是上面提到的Java的特点的编译与解释并存的解释


10.什么是Java程序主类?应用程序和小程序的主类有何不同?

一个程序中可以有多个类,但只能有一个类是主类

在Java应用程序中,这个主类是指包含main()方法的类。而在Java小程序中,这个主类是一个继承自系统类JApplet或Applet的子类。应用程序的主类不一定要求是public类,但小程序的主类要求必须是public类。主类是Java程序执行的入口点


11.Java应用程序与小程序之间有那些差别?

简单说应用程序是从主线程启动(main())。applet小程序没有main方法,主要是嵌在浏览器页面上运行(调用init()线程或者run()来启动),嵌入浏览器这点跟flash的小游戏类似


12.Oracle JDK和Open JDK对比

Oracle JDK版本将每三年发布一次,而Open JDK版本每三个月发布一次

Open JDK是一个参考模型并且是完全开源的,而Oracle JDK是OpenJDK的一个实现,并不是完全开源的;

Oracle JDK比OpenJDK更稳定。OpenJDK和Oracle JDK的代码几乎相同,但Oracle JDK有更多的类和一些错误修复。因此,如果想开发企业/商业软件,建议您选择Oracle JDK,因为它经过了彻底的测试和稳定。某些情况下,有些人提到在使用OpenJDK 可能会遇到了许多应用程序崩溃的问题,但是,只需切换到Oracle JDK就可以解决问题

在响应性和JVM性能方面,Oracle JDK与OpenJDK相比提供了更好的性能;
Oracle JDK不会为即将发布的版本提供长期支持,用户每次都必须通过更新到最新版本获得支持来获取最新版本;
Oracle JDK根据二进制代码许可协议获得许可,而OpenJDK根据GPL v2许可获得许可


13.switch是否能作用在byte上,是否能作用在long上,是否能作用在String上

在 Java 5 以前,switch(expr)中,expr只能是 byte、short、char、int
从 Java 5 开始,Java中引入了枚举类型,expr也可以是enum类型
从 Java 7 开始,expr还可以是字符串(String),但是长整型(long)在目前所有的版本中都是不可以的


14.用最有效率的方法计算2乘以8

左乘右除:2 << 3(左移3位相当于乘以2的3次方,右移3位相当于除以2的3次方)


15.Math.round(11.5)等于多少?Math.round(-11.5)等于多少

四舍五入的原理是在参数上加0.5然后进行下取整。

Math.round(11.5)的返回值是12,Math.round(-11.5)的返回值是-11


16.float f=3.4;是否正确?

不正确。3.4是双精度数,将双精度型(double)赋值给浮点型(float)属于下转型(down-casting,也称为窄化)会造成精度损失,因此需要强制类型转换float f =(float)3.4; 或者写成 float f =3.4F;。


17.short s1 = 1;。s1 = s1 + 1;有错吗? s1 += 1;有错吗?

对于short s1 = 1; s1 = s1 + 1;由于1是int类型,因此s1+1运算结果也是int型,需要强制转换类型才能赋值给 short 型。
而short s1 = 1; s1 += 1;可以正确编译,因为 s1+= 1;相当于s1 = (short(s1 + 1);其中有隐含的强制类型转换


18.Java语言采用何种编码方案?有何特点?

Java语言采用Unicode编码标准,Unicode(标准码),它为每个字符制订了一个唯一的数值,因此在任何的语言,平台,程序都可以放心使用。


19.注释

什么是Java注释:用于解释说明程序的文字

注释描述
单行注释// 注释文字
多行注释/* 注释文字 */
文档注释/** 注释文字 */

在程序中,尤其是复杂的程序中,适当地加入注释可以增加程序的可读性,有利于程序的修改、调试和交流。注释的内容在程序编译的时候会被忽视,不会产生目标代码,注释的部分不会对程序的执行结果产生任何影响。

**注意事项:**多行和文档注释都不能嵌套使用


20.访问修饰符?作用域?

public、protected、private、default(默认)

定义:Java中,可以使用访问修饰符来保护对类、变量、方法和构造方法的访问

Java支持4种不同的访问权限

访问修饰符本类同包子类父类
private
默认(default)
protected
public

private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
default (即缺省,什么也不写,不使用任何关键字): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
public : 对所有类可见。使用对象:类、接口、变量、方法


21.&和&&的区别?

&位逻辑运算符、&&逻辑运算符(短路)

&运算符有两种用法
1.位与
2.逻辑与

&&运算符是短路与运算。逻辑与跟短路与的差别是非常巨大的,虽然二者都要求运算符左右两端的布尔值都是true整个表达式的值才是true。&&之所以称为短路运算,是因为如果&&左边的表达式的值是 false,右边的表达式会被直接短路掉,不会进行运算
注意:逻辑或运算符(|)和短路或运算符(||)的差别也是如此


22.Java有没有goto?

goto是Java中的保留字,在目前版本的Java中没有使用


23.final有什么用?

用于修饰类、属性和方法

类:不可被继承
属性:常量
方法:不可重写

被final修饰的类不可以被继承
被final修饰的方法不可以被重写
被final修饰的变量不可以被改变,被final修饰不可变的是变量的引用,而不是引用指向的内容,引用指向的内容是可以改变的(创建一个新的内存地址指向它)


24.final、finally、finalize区别

final:可以修饰类、变量、方法,修饰类表示该类不能被继承、修饰方法表示该方法不能被重写、修饰变量表示该变量是一个常量不能被重新赋值
finally:一般作用在try-catch代码块中,在处理异常的时候,通常将一定要执行的代码方法finally代码块
中,表示不管是否出现异常,该代码块都会执行,一般用来存放一些关闭资源的代码。
finalize:是一个方法,属于Object类的一个方法,而Object类是所有类的父类,该方法一般由垃圾回收器来调用,当调用System.gc()方法的时候,由垃圾回收器调用finalize(),回收垃圾,一个对象是否可回收的


25.this关键字用法(3种)

this是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针

1.普通的直接引用,this相当于是指向当前对象本身
2.形参与成员名字重名,用this来区分
3.引用本类的构造函数:this(参数)


26.super关键字用法(3种)

super可以理解为是指向自己超(父)类对象的一个指针,而这个超类指的是离自己最近的一个父类。指向对象父类的一个指针(最近一个)

1.普通的直接引用
与this类似,super相当于是指向当前对象的父类的引用,这样就可以用super.xxx来引用父类的成员

2.子类中的成员变量或方法与父类中的成员变量或方法同名时,用super进行区分

3.引用父类构造函数:super(参数)

关键字函数描述
super(参数)调用父类中的某一个构造函数(应该为构造函数中的第一条语句)
this(参数)调用本类中另一种形式的构造函数(应该为构造函数中的第一条语句)

不能同时存在


27.this与super区别

thissuper
代表当前对象名(在程序中易产生二义性之处,应使用this来指明当前对象;如果函数的形参与类中的成员数据同名,这时需用this来指明成员变量名。this()在本类内调用本类的其它构造方法引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或函数,基类与派生类中有相同成员定义时如:super.变量名 super.成员函数据名(实参)。super()在子类中调用父类的构造方法
this是一个Java关键字。指向本对象的指针super是一个Java关键字。指向父类

1.都必须是第一行
尽管可以用this()调用一个构造器,但却不能调用两个

2.不能共存
this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过

3.都不可在static中使用
this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量、static方法、static语句块


28.static存在的主要意义?

static的主要意义是在于创建独立于具体对象的域变量或者方法。以致于即使没有创建对象,也能使用属性和调用方法

static关键字还有一个比较关键的作用就是用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次

static块可以用来优化程序性能,是因为static特性:只会在类加载的时候执行一次。因此,很多时候会将一些只需要进行一次的初始化操作都放在static代码块中进行


29.static独特之处

1.被static修饰的变量或者方法是独立于该类的任何对象
也就是说,这些变量和方法不属于任何一个实例对象,而是被类的实例对象所共享

2.在该类被第一次加载的时候,就会去加载被static修饰的部分,而且只在类第一次使用时加载并进行初始化
注意:第一次用就要初始化,后面根据需要是可以再次赋值

3.static变量值在类加载的时候分配空间,以后创建类对象的时候不会重新分配。赋值的话,是可以任意赋值

4.被static修饰的变量或者方法是优先于对象存在的,也就是说当一个类加载完毕之后,即便没有创建对象,也可以去访问


30.static应用场景

因为static是被类的实例对象所共享,因此如果某个成员变量是被所有对象所共享的,那么这个成员变量就应该定义为静态变量
1.静态代码块
2.修饰成员变量
3.修饰成员方法
4.修饰类(只能修饰内部类也就是静态内部类)
5.静态导包


31.static注意事项

1.静态只能访问静态
2.非静态既可以访问非静态的,也可以访问静态的


32.break、continue、return区别及作用

关键字描述
break跳出总上一层循环,不再执行循环(结束当前循环体)
continue跳出本次循环,继续执行下次循环(结束正在执行的循环,进入下一个循环条件)
return程序返回,不再执行下面的代码(结束当前的方法,直接返回)

33.如何跳出当前的多重嵌套循环?

break。在Java中,要想跳出多重循环,可以在外面的循环语句前定义一个标号,然后在里层循环体的代码中使用带有标号的break语句,即可跳出外层循环

ok: for (int i = 0; i < 10; i++) {
		for (int j = 0; j < 10; j++) {
			System.out.println("i=" + i + ",j=" + j);
			if (j == 5) {
				break ok;
			}
	 }
}

34.面向对象和面向过程区别?

面向过程
面向过程是具体化的,流程化的,解决一个问题,需要一步一步的分析,一步一步的实现

(1)优点
性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机、嵌入式开发、Linux/Unix等。一般采用面向过程开发,性能是最重要的因素

(2)缺点
没有面向对象易维护、易复用、易扩展

面向对象
面向对象是模型化的,只需抽象出一个类,这是一个封闭的盒子,在这里拥有数据也拥有解决问题的方法。需要什么功能直接使用就可以了,不必去一步一步的实现,至于这个功能是如何实现的,管我们什么事?我们会用就可以了

面向对象的底层其实还是面向过程,把面向过程抽象成类,然后封装,方便使用的就是面向对象

(1)优点
易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更加易于维护

(2)缺点
性能比面向过程低


35.面向对象三(四)大特性

(1)抽象
抽象是将一类对象的共同特征抽象出来构造类的过程,包括数据抽象和行为抽象两方面。抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什么

(2)封装
封装把一个对象的属性私有化,同时提供一些可以被外界访问的属性的方法,如果属性不想被外界访问,大可不必提供方法给外界访问。但是如果一个类没有提供给外界访问的方法,那么这个类也没有什么意义
隐藏对象的属性和实现细节,仅对外提供公共访问方式,将变化隔离,便于使用,提高复用性和安全性

(3)继承
继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。通过使用继承能够非常方便地复用以前的代码
1.子类拥有父类非private的属性和方法。default必须在同包
2.子类可以拥有自己属性和方法,即子类可以对父类进行扩展
3.子类可以用自己的方式实现父类的方法(重写)
继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。通过使用继承可以提高代码复用性。继承是多态的前提

(4)多态
指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的,方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量到底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定


36.什么是多态机制?Java语言是如何实现多态的?

指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定

在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性

编译时多态:静态的,主要是指方法的重载
运行时多态:动态的,主要是子类重写父类方法


37.面向对象五大基本原则是什么(可选)

单一职责原则(SRP)
类的功能要单一,不能包罗万象,跟杂货铺似的

开放封闭原则(OCP,Open-Close Principle)
一个模块对于拓展是开放的,对于修改是封闭的,想要增加功能热烈欢迎,想要修改,一万个不乐意

里氏替换原则(LSP)
指的是所有引用基类的地方都可以透明的使用其子类的对象
可以理解为:只要有父类出现的地方,都可以使用子类来替代。而且不会出现任何错误或者异常。但是反过来却不行。子类出现的地方,不能使用父类来替代。

里式替换原则LSP(the Liskov Substitution Principle LSP)
子类可以替换父类。出现在父类能够出现的任何地方。比如你能代表你爸去你姥姥家干活。哈哈

依赖倒置原则DIP(the Dependency Inversion Principle DIP)
高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。抽象不应该依赖于具体实现,具体实现应该依赖于抽象。就是你出国要说你是中国人,而不能说你是哪个村子的。比如说中国人是抽象的,下面有具体的xx省,xx市,xx县。你要依赖的抽象是中国人,而不是xx村的。

接口分离原则ISP(the Interface Segregation Principle ISP)
设计时采用多个与特定客户类有关的接口比采用一个通用的接口要好。就比如一个手机拥有打电话,看视频,玩游戏等功能,把这几个功能拆分成不同的接口,比在一个接口里要好的多


38.抽象类、接口对比?

抽象类是用来捕捉子类的通用特性的。接口是抽象方法的集合
从设计层面来说,抽象类是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范

相同点
1.接口和抽象类都不能实例化
2.都位于继承的顶端,用于被其他实现或继承
3.都包含抽象方法,其子类都必须覆写这些抽象方法

不同点

参数抽象类接口
声明abstract声明interface声明
实现子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现子类使用implements关键字来实现接口。它需要提供接口中所有声明的方法的实现
构造器可以有构造器不能有构造器
访问修饰符可以是任意访问修饰符接口方法默认修饰符是public。并且不允许定义为private或者protected
多继承一个类最多只能继承一个抽象类一个类可以实现多个接口
字段声明字段声明可以是任意的默认都是public static final的

备注:Java 8中接口中引入默认方法和静态方法,以此来减少抽象类和接口之间的差异。
现在,可以为接口提供默认实现的方法了,并且不用强制子类来实现它

接口和抽象类各有优缺点,在接口和抽象类的选择上,必须遵守这样一个原则:
行为模型应该总是通过接口而不是抽象类定义,所以通常是优先选用接口,尽量少用抽象类。
选择抽象类的时候通常是如下情况:需要定义子类的行为,又要为子类提供通用的功能


39.普通类和抽象类有哪些区别?

普通类抽象类
不能包含抽象方法可以包含抽象方法、普通方法
可以直接实例化不能直接实例化

40.抽象类能使用final修饰吗?

不能,定义抽象类就是让其他类继承的,如果定义为final该类就不能被继承,这样彼此就会产生矛盾,所以final不能修饰抽象类。


41.创建一个对象用什么关键字?对象实例与对象引用有何不同?

new关键字。new创建对象实例(对象实例在堆内存中)
对象引用指向对象实例(对象引用存放在栈内存中)

一个对象引用可以指向0个或1个对象(一根绳子可以不系气球,也可以系一个气球),一个对象可以有n个引用指向它(可以用n条绳子系住一个气球)


42.变量与方法?

变量:在程序执行的过程中,在某个范围内其值可以发生改变的量。从本质上讲,变量其实是内存中的一小块区域
成员变量:方法外部,类内部定义的变量
局部变量:类的方法中的变量

成员变量和局部变量区别

成员变量局部变量
作用域针对整个类有效只在某个范围内有效(一般指的就是方法,语句体内)
存储位置随着对象的创建而存在,随着对象的消失而消失,存储在堆内存中在方法被调用,或者语句被执行的时候存在,存储在栈内存中。当方法调用完,或者语句结束后,就自动释放
生命周期随着对象的创建而存在,随着对象的消失而消失当方法调用完,或者语句结束后,就自动释放
初始值有默认初始值没有默认初始值,使用前必须赋值

使用原则:在使用变量时需要遵循的原则为:就近原则。首先在局部范围找,有就使用;接着在成员位置找


43.在Java中定义一个不做事且没有参数的构造方法的作用?

Java程序在执行子类的构造方法之前,如果没有用super()来调用父类特定的构造方法,则会调用父类中“没有参数的构造方法”。因此,如果父类中只定义了有参数的构造方法,而在子类的构造方法中又没有用super()来调用父类中特定的构造方法,则编译时将发生错误,因为Java程序在父类中找不到没有参数的构造方法可供执行。解决办法是在父类里加上一个不做事且没有参数的构造方法


44.在调用子类构造方法之前会先调用父类没有参数的构造方法,其目的是?

帮助子类做初始化工作


45.一个类的构造方法的作用是什么?若一个类没有声明构造方法,改程序能正确执行吗?为什么?

主要作用是完成对类对象的初始化工作。
可以执行。因为一个类即使没有声明构造方法也会有默认的不带参数的构造方法


46.构造方法有哪些特性?

(1)名字与类名相同
(2)没有返回值,但不能用void声明构造函数
(3)生成类的对象时自动执行,无需调用


47.静态变量和实例变量区别

静态变量实例变量
静态变量由于不属于任何实例对象,属于类的,所以在内存中只会有一份,在类的加载过程中,JVM只为静态变量分配一次内存空间每次创建对象,都会为每个对象分配成员变量内存空间,实例变量是属于实例对象的,在内存中,创建几次对象,就有几份成员变量
静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。static成员变量的初始化顺序按照定义的顺序进行初始化 非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。static成员变量的初始化顺序按照定义的顺序进行初始化静态变量由于不属于任何实例对象,属于类的,所以在内存中只会有一份,在类的加载过程中,JVM只为静态变量分配一次内存空间静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化

48.静态方法和实例方法有何不同?

静态方法实例方法
外部调用类名.方法名、实例化对象名.方法名(不推荐)。调用静态方法可以无需创建对象对象名.方法名
访问本类成员只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法实例方法则无此限制

49.在一个静态方法内调用一个非静态成员为什么是非法的?

由于静态方法可以不通过对象进行调用,因此在静态方法里,不能调用其他非静态变量,也不可以访问非静态变量成员


50.什么是方法的返回值?返回值的作用是什么?

方法的返回值是指获取到的某个方法体中的代码执行后产生的结果(前提是该方法可能产生结果)
返回值的作用:接收结果,使得它可以用于其他的操作


51.什么是内部类?

在Java中,可以将一个类的定义放在另外一个类的定义内部,这就是内部类。内部类本身就是类的一个属性,与其他属性定义方式一致


52.内部类分类(4种)

内部类可以分为四种:成员内部类、局部内部类、匿名内部类和静态内部类

(1)静态内部类

静态内部类定义
定义在类内部的静态类,就是静态内部类

public class Outer {
	private static int radius = 1;

	static class StaticInner {
		public void visit() {
			System.out.println("visit outer static  variable:" + radius);
		}
	}
}

静态内部类创建访问
静态内部类可以访问外部类所有的静态变量,而不可访问外部类的非静态变量;静态内部类的创建方式,new 外部类.静态内部类()

Outer.StaticInner inner = new Outer.StaticInner();
inner.visit();

(2)成员内部类

成员内部类定义
定义在类内部,成员位置上的非静态类,就是成员内部类

public class Outer {
    private static  int radius = 1;
    private int count =2;
    
     class Inner {
        public void visit() {
            System.out.println("visit outer static  variable:" + radius);
            System.out.println("visit outer   variable:" + count);
        }
    }
}

成员内部类创建访问
成员内部类可以访问外部类所有的变量和方法,包括静态和非静态、私有和公有。成员内部类依赖于外部类的实例,创建方式:new 外部类.new 内部类()

Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.visit();

(3)局部内部类

局部内部类定义
定义在方法中的内部类,就是局部内部类

public class Outer {
	private int out_a = 1;
	private static int STATIC_b = 2;

	public void testFunctionClass() {
		int inner_c = 3;
		class Inner {
			private void fun() {
				System.out.println(out_a);
				System.out.println(STATIC_b);
				System.out.println(inner_c);
			}
		}
		Inner inner = new Inner();
		inner.fun();
	}

	public static void testStaticFunctionClass() {
		int d = 3;
		class Inner {
			private void fun() {
				// System.out.println(out_a); 编译错误,定义在静态方法中的局部类不可以访问外部类的实例变量
				System.out.println(STATIC_b);
				System.out.println(d);
			}
		}
		Inner inner = new Inner();
		inner.fun();
	}
}

定义在实例方法中的局部类可以访问外部类的所有变量和方法
定义在静态方法中的局部类只能访问外部类的静态变量和方法

局部内部类的创建访问方式
局部内部类的创建方式,在对应方法内,new 内部类()

public void testFunctionClass() {
	int inner_c = 3;
	class Inner {
		private void fun() {
			System.out.println(out_a);
			System.out.println(STATIC_b);
			System.out.println(inner_c);
		}
	}
	Inner inner = new Inner();
	inner.fun();
}

(4)匿名内部类

匿名内部类定义
匿名内部类就是没有名字的内部类,日常开发中使用的比较多。

public class Outer {
	private void test(final int i) {
		Service service = new Service() {
			public void method() {
				for (int j = 0; j < i; j++) {
					System.out.println("匿名内部类");
				}
			}
		}.method();
	}
}

// 匿名内部类必须继承或实现一个已有的接口
interface Service {
	void method();
}

除了没有名字,匿名内部类还有以下特点:
(1)匿名内部类必须继承一个抽象类或者实现一个接口
(2)匿名内部类不能定义任何静态成员和静态方法
(3)当所在的方法的形参需要被匿名内部类使用时,必须声明为final
(4)匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。

匿名内部类创建方式

new 类/接口{ 
  //匿名内部类实现部分
}

53.内部类优点

(1)一个内部类对象可以访问创建它的外部类对象的内容,包括私有数据
(2)内部类不为同一包的其他类所见,具有很好的封装性
(3)内部类有效实现了“多重继承”,优化Java单继承的缺陷
(4)匿名内部类可以很方便的定义回调


54.内部类应用场景

(1)多算法场合
(2)解决一些非面向对象的语句块
(3)适当使用内部类,使得代码更加灵活和富有扩展性
(4)当某个类除了它的外部类,不再被其他的类使用时


55.局部内部类和匿名内部类访问局部变量的时候,为什么变量必须要加上final?

局部内部类和匿名内部类访问局部变量的时候,为什么变量必须要加上final呢?它内部原理是什么呢?

public class Outer {
	void outMethod() {
		final int a = 10;
		class Inner {
			void innerMethod() {
				System.out.println(a);
			}
		}
	}
}

以上例子,为什么要加final呢?
因为生命周期不一致,局部变量直接存储在栈中,当方法执行结束后,非final的局部变量就被销毁。而局部内部类对局部变量的引用依然存在,如果局部内部类要调用局部变量时,就会出错。加了final,可以确保局部内部类使用的变量与外层的局部变量区分开,解决了这个问题。


56.内部类相关,看程序说出运行结果

public class Outer {
	private int age = 12;

	class Inner {
		private int age = 13;

		public void print() {
			int age = 14;
			System.out.println("局部变量:" + age);
			System.out.println("内部类变量:" + this.age);
			System.out.println("外部类变量:" + Outer.this.age);
		}
	}

	public static void main(String[] args) {
		Outer.Inner in = new Outer().new Inner();
		in.print();
	}
}

运行结果:

局部变量:14
内部类变量:13
外部类变量:12

57.构造器(constructor)是否可被重写(override)

构造器不能被继承,因此不能被重写。可以被重载


58.重载(Overload)和重写(Override)的区别

方法的重载和重写都是实现多态的方式
重载:实现的是编译时的多态性
重写:实现的是运行时的多态性

重写:发生在父子类中,方法名、参数列表必须相同,返回值小于等于父类,抛出的异常小于等于父类,访问修饰符大于等于父类(里氏代换原则);如果父类方法访问修饰符为private则子类中就不是重写


59.重载方法能否根据返回类型进行区分?

重载:发生在同一个类中,方法名相同参数列表不同(参数类型不同、个数不同、顺序不同),与方法返回值和访问修饰符无关,即重载的方法不能根据返回类型进行区分


60.==和equals区别是什么

(1)==:判断两个对象的地址是不是相等
判断两个对象是不是同一个对象。
基本数据类型 == 比较的是值
引用数据类型 == 比较的是内存地址

(2)equals():判断两个对象是否相等
①没有覆盖equals()。等价于通过“==”比较这两个对象
②覆盖了equals()。按覆盖equals()方法来两个对象的内容相等;若它们的内容相等,则返回 true(两个对象相等)

String中的equals方法是被重写过的,因为Object的equals()是比较的对象的内存地址,而String的equals方法比较的是对象的值。
当创建String类型的对象时,虚拟机会在常量池中查找有没有已经存在的值和要创建的值相同的对象,如果有就把它赋给当前引用。如果没有就在常量池中重新创建一个String对象


61.hashCode()与equals()(重要)

HashSet如何检查重复
两个对象的hashCode()相同,则equals()也一定为 true,对吗?

hashCode和equals方法的关系
面试官可能会问你:“你重写过hashcode和equals么,为什么重写equals时必须重写hashCode方法?”

hashCode()介绍
hashCode()作用是获取哈希码,也称为散列码;实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。hashCode()定义在JDK的Object.java中,这就意味着Java中的任何类都包含有hashCode()函数。

散列表存储的是键值对(key-value)。特点:能根据“键”快速的检索出对应的“值”。这其中就利用到了散列码(可以快速找到所需要的对象)

为什么要有hashCode?
以“HashSet如何检查重复”为例子来说明为什么要有hashCode:
当把对象加入HashSet时,HashSet会先计算对象的hashcode值来判断对象加入的位置,同时也会与其他已经加入的对象的hashcode值作比较,如果没有相符的hashcode,HashSet会假设对象没有重复出现。但是如果发现有相同hashcode值的对象,这时会调用equals()方法来检查hashcode相等的对象是否真的相同。如果两者相同,HashSet就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置。这样就大大减少了equals的次数,相应就大大提高了执行速度

hashCode()与equals()的相关规定:
(1)如果两个对象相等,则hashcode一定也是相同的。对两个对象分别调用equals方法都返回true。hashcode值相同,它们也不一定相等
(2)若equals()被覆盖,则hashcode()也必须被覆盖
(3)hashCode()的默认行为是对堆上的对象产生独特值。如果没有重写hashCode(),则该class的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)
(4)equals()的默认行为是执行==的比较。也就是说会去测试两个引用是否对上heap(堆)上同一个对象。如果equals()没有被覆盖过,两个对象永远都不会被视为相同的。因此不同的对象有不同的字节组合


62.对象相等与引用相等,两者有什么不同?

对象相等:比的是内存中存放的内容是否相等
引用相等:比较的是他们指向的内存地址是否相等


63.值传递和引用传递有什么区别

值传递:指的是在方法调用时,传递的参数是按值的拷贝传递,传递的是值的拷贝,也就是说传递后就互不相关了
引用传递:指的是在方法调用时,传递的参数是按引用进行传递,其实传递的引用的地址,也就是变量所对应的内存空间的地址。传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间)


64.JDK中常用的包

常用包描述
java.lang系统的基础类
java.io所有输入输出有关的类,比如文件操作等
java.nio完善io包中的功能,提高io包中性能而写的一个新包
java.net与网络有关的类
java.util系统辅助类,特别是集合类
java.sql数据库操作的类

65.import java和javax有什么区别

刚开始Java API所必需的包是Java开头的包,javax当时只是扩展API包来使用。然而随着时间的推移,javax逐渐的扩展成为Java API的组成部分。但是,将扩展从javax包移动到java包将是太麻烦了,最终会破坏一堆现有的代码。因此,最终决定javax包将成为标准API的一部分。所以,实际上java和javax没有区别。这都是一个名字


66.Java中IO流分为几种?

划分方向种类
流的流向划分输入流和输出流
操作单元划分字节流和字符流
流的角色划分节点流和处理流

Java IO流共涉及40多个类,这些类看上去很杂乱,但实际上很有规则,而且彼此之间存在非常紧密的联系,Java I0流的40多个类都是从如下4个抽象类基类中派生出来的。

InputStream(字节输入流)、Reader(字符输入流): 读
OutputStream(字节输出流)、Writer(字符输出流): 写

节点流(低级流:直接跟输入输出源对接)
FileInputStream/FileOutputStream/FileReader/FileWriter/PrintStream/PrintWriter.

处理流(高级流:建立在低级流的基础上)
转换流:InputStreamReader/OutputStreamWriter,字节流转字符流/字符流转字节流
缓冲流:BufferedInputStream/BufferedOutputStream BufferedReader/BufferedReader可对节点流经行包装,使读写更快


67.BIO、NIO、AIO有什么区别?

IO流描述
BIO(Block IO,同步阻塞式IO)平常使用的传统IO,特点是模式简单使用方便,并发处理能力低
NIO(Non IO,同步非阻塞IO)传统IO的升级,客户端和服务器端通过Channel(通道)通讯,实现了多路复用
AIO(Asynchronous IO)NIO的升级,也叫NIO2,实现了异步非堵塞IO,异步IO的操作基于事件和回调机制

1.BIO(Blocking I/O)

同步阻塞I/O模式。数据的读取写入必须阻塞在一个线程内等待其完成。在活动连接数不是特别高(小于单机1000)的情况下,这种模型是比较不错的,可以让每一个连接专注于自己的I/O并且编程模型简单,也不用过多考虑系统的过载、限流等问题。线程池本身就是一个天然的漏斗,可以缓冲一些系统处理不了的连接或请求。但是,当面对十万甚至百万级连接的时候,传统的BIO模型是无能为力的。因此,需要一种更高效的I/O处理模型来应对更高的并发量

2.NIO(New I/O)

同步非阻塞的I/O模型。在Java 1.4中引入了NIO框架,对应java.nio包,提供了 Channel、Selector、Buffer等抽象,NIO中的N可以理解为Non-blocking,不单纯是New。它支持面向缓冲的,基于通道的I/O操作方法。

NIO提供了与传统BIO模型中Socket和ServerSocket对应的SocketChannel和ServerSocketChannel两种不同的套接字通道实现,两种通道都支持阻塞和非阻塞两种模式。阻塞模式使用就像传统中的支持一样,比较简单,但是性能和可靠性都不好

IO流描述
同步阻塞I/O低负载、低并发的应用程序,提升开发速率和更好的维护性
同步非阻塞的I/O高负载、高并发的(网络)应用,应使用NIO的非阻塞模式来开发

3.AIO(Asynchronous I/O)

AIO也就是NIO 2。在Java 7中引入了NIO的改进版NIO 2,它是异步非阻塞的IO模型。异步IO是基于事件回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。AIO是异步IO的缩写,虽然NIO在网络操作中,提供了非阻塞的方法,但是NIO的IO行为还是同步的。对于NIO来说,业务线程是在IO操作准备好时,得到通知,接着就由这个线程自行进行IO操作,IO操作本身是同步的。目前来说AIO的应用还不是很广泛


Files常用方法?

Files方法描述
Files.exists()检测文件路径是否存在
Files.createFile()创建文件
Files.createDirectory()创建文件夹
Files.delete()删除一个文件或目录
Files.copy()复制文件
Files.move()移动文件
Files.size()查看文件个数
Files.read()读取文件
Files.write()写入文件

69.什么是反射机制?

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

静态编译和动态编译
静态编译:在编译时确定类型,绑定对象
动态编译:运行时确定类型,绑定对象


70.反射机制优缺点

优点:运行期类型的判断,动态加载类,提高代码灵活度
缺点:性能瓶颈。反射相当于一系列解释操作,通知JVM要做的事情,性能比直接的Java代码要慢很多


71.反射机制的应用场景有哪些?

反射是框架设计的灵魂
在平时的项目开发过程中,基本上很少会直接使用到反射机制,但这不能说明反射机制没有用,实际上有很多设计、开发都与反射机制有关
(1)模块化的开发,通过反射去调用对应的字节码
(2)动态代理设计模式也采用了反射机制
(3)日常使用的Spring/Hibernate等框架也大量使用到了反射机制

1.在使用JDBC连接数据库时使用Class.forName()通过反射加载数据库的驱动程序

2.Spring框架也用到很多反射机制,最经典的就是xml的配置模式
(1)Spring通过XML配置模式装载Bean的过程
(2)将程序内所有XML或Properties配置文件加载入内存中
(3)Java类里面解析xml或properties里面的内容,得到对应实体类的字节码字符串以及相关的属性信息
(4)使用反射机制,根据这个字符串获得某个类的Class实例
(5)动态配置实例的属性


72.Java获取反射(三种方法)

1.通过new对象实现反射机制

// 方式一(通过建立对象)
Student stu = new Student();
Class classobj1 = stu.getClass();

2.通过路径实现反射机制

// 方式二(所在通过路径-相对路径)全限定类型
Class classobj2 = Class.forName("com.my.Student");

3.通过类名实现反射机制

// 方式三(通过类名)
Class classobj3 = Student.class;

73.字符型常量和字符串常量区别

字符常量字符串常量
形式上单引号引起的一个字符双引号引起的若干个字符
含义上相当于一个整形值(ASCII值),可以参加表达式运算代表一个地址值(该字符串在内存中存放位置)
占内存大小只占一个字节占若干个字节(至少一个字符结束标志)

74.什么是字符串常量池?

字符串常量池位于堆内存中,专门用来存储字符串常量,可以提高内存的使用率,避免开辟多块空间存储相同的字符串,在创建字符串时JVM会首先检查字符串常量池,如果该字符串已经存在池中,则返回它的引用,如果不存在,则实例化一个字符串放到池中,并返回其引用


75.String是最基本的数据类型吗

不是。Java中的基本数据类型只有8个 :byte、short、int、long、float、double、char、boolean;除了基本类型(primitive type),剩下的都是引用类型(referencetype),Java 5以后引入的枚举类型也算是一种比较特殊的引用类型

String底层就是一个char类型的数组,只是使用的时候开发者不需要直接操作底层数组,用更加简便的方式即可完成对字符串的使用


76.String有哪些特性

(1)不变性
String是只读字符串,是一个典型的immutable 对象,对它进行任何操作,其实都是创建一个新的对象,再把引用指向该对象

(2)不变模式
主要作用在于当一个对象需要被多线程共享并频繁访问时,可以保证数据的一致性

(3)常量池优化
String对象创建之后,会在字符串常量池中进行缓存,如果下次创建同样的对象时,会直接返回缓存的引用

(4)final
使用final来定义String类,表示String类不能被继承,提高了系统的安全性


77.String为什么是不可变的?

简单来说就是String类利用了final修饰的char类型数组存储字符,源码如下

private final char value[];

78.String真的是不可变的吗?

我觉得如果别人问这个问题的话,回答不可变就可以了

(1)String不可变,但不代表引用不可变

String str = "Hello";
str = str + " World";
System.out.println("str=" + str);

// 结果:
str=Hello World

解析:实际上,原来String的内容是不变的,只是str由原来指向“Hello”的内存地址转为指向“Hello World”的内存地址而已,也就是说多开辟了一块内存区域给“Hello World”字符串。

(2)通过反射是可以修改所谓的“不可变”对象

// 创建字符串"Hello World", 并赋给引用s
String s = "Hello World";
System.out.println("s = " + s); // Hello World
// 获取String类中的value字段
Field valueFieldOfString = String.class.getDeclaredField("value");
// 改变value属性的访问权限
valueFieldOfString.setAccessible(true);
// 获取s对象上的value属性的值
char[] value = (char[]) valueFieldOfString.get(s);
// 改变value所引用的数组中的第5个字符
value[5] = '_';
System.out.println("s = " + s); // Hello_World

// 结果:
s = Hello World
s = Hello_World

解析:用反射可以访问私有成员,然后反射出String对象中的value属性,进而改变通过获得的value引用改变数组的结构。但是一般不会这么做,这里只是简单提一下有这个东西


79.是否可以继承String类

String类是final类,不可以被继承


80.String str="i"与 String str=new String(“i”)一样吗?

不一样。因为内存的分配方式不一样。String str="i"的方式,Java虚拟机会将其分配到常量池中;而String str=new String(“i”)则会被分到堆内存中


81.String s = new String(“xyz”);创建了几个字符串对象

两个对象,一个是静态区的"xyz",一个是用new创建在堆上的对象。

// str1指向静态区
String str1 = "hello";
// str2指向堆上的对象
String str2 = new String("hello");
String str3 = "hello";
String str4 = new String("hello");
System.out.println(str1.equals(str2)); // true
System.out.println(str2.equals(str4)); // true
System.out.println(str1 == str3); // true
System.out.println(str1 == str2); // false
System.out.println(str2 == str4); // false
System.out.println(str2 == "hello"); // false
System.out.println(str2 == "hello"); // true

82.如何将字符串反转?

使用StringBuilder或者StringBuffer的reverse()方法。反转:倒序输出

StringBuffer stringBuffer = new StringBuffer(); // StringBuffer reverse
stringBuffer.append("abcdefg");
System.out.println(stringBuffer.reverse()); // gfedcba
StringBuilder stringBuilder = new StringBuilder(); // StringBuilder reverse
stringBuilder.append("abcdefg");
System.out.println(stringBuilder.reverse()); // gfedcba

83.数组有没有length()方法?String有没有length()方法

数组没有length()方法,有length的属性。
String有length()方法。
JavaScript中,获得字符串的长度是通过length属性得到的,这一点容易和Java混淆


84.String类的常用方法?

方法描述
indexOf()返回指定字符的索引
charAt()返回指定索引处的字符
replace()字符串替换
trim()去除字符串两端空白
split()分割字符串,返回一个分割后的字符串数组
getBytes()返回字符串的 byte 类型数组
length()返回字符串长度
toLowerCase()将字符串转成小写字母
toUpperCase()将字符串转成大写字符
substring()截取字符串
equals()字符串比较

85.在使用HashMap的时候,用String做key有什么好处?

HashMap内部实现是通过key的hashcode来确定value的存储位置,因为字符串是不可变的,所以当创建字符串时,它的hashcode被缓存下来,不需要再次计算,所以相比于其他对象更快


86.String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的

(1)可变性
String类中使用字符数组保存字符串(private final char value[]),String对象是不可变的
StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串,char[] value,这两种对象都是可变的。

(2)线程安全性
String中的对象是不可变的,也就可以理解为常量,线程安全。
AbstractStringBuilder是StringBuilder与StringBuffer的公共父类,定义了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。
StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。
StringBuilder并没有对方法进行加同步锁,所以是非线程安全的。

(3)性能
每次对String类型进行改变的时候,都会生成一个新的String对象,然后将指针指向新的String对象。
StringBuffer每次都会对StringBuffer对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用StirngBuilder相比使用StringBuffer 仅能获得10%~15%左右的性能提升,但却要冒多线程不安全的风险

对于三者使用的总结

操作场景使用选择
如果要操作少量的数据用String
单线程操作字符串缓冲区下操作大量数据StringBuilder
多线程操作字符串缓冲区下操作大量数据StringBuffer

87.自动装箱与拆箱

自动装箱:将基本类型用它们对应的引用类型包装起来
自动拆箱:将包装类型转换为基本数据类型


88.int和Integer有什么区别?

Java是一个近乎纯洁的面向对象编程语言,但是为了编程的方便还是引入了基本数据类型,但是为了能够将这些基本数据类型当成对象操作,Java 为每一个基本数据类型都引入了对应的包装类型(wrapper class),int的包装类就是Integer,从Java 5开始引入了自动装箱/拆箱机制,使得二者可以相互转换

Java为每个原始类型提供了包装类型:
原始类型:boolean,char,byte,short,int,long,float,double
包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double


89.Integer a= 127与Integer b = 127相等?

对于对象引用类型:==比较的是对象的内存地址
对于基本数据类型:==比较的是值

如果整型字面量的值在-128到127之间,那么自动装箱时不会new新的Integer对象,而是直接引用常量池中的Integer对象,超过范围 a1==b1的结果是false

Integer a = new Integer(3);
Integer b = 3; // 将3自动装箱成Integer类型
int c = 3;
System.out.println(a == b); // false	两个引用没有引用同一对象
System.out.println(a == c); // true		a自动拆箱成int类型再和c比较
System.out.println(b == c); // true

Integer a1 = 128;
Integer b1 = 128;
System.out.println(a1 == b1); // false

Integer a2 = 127;
Integer b2 = 127;
System.out.println(a2 == b2); // true
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Java基础高频面试题包括以下内容: 1. 你是怎么理解面向对象的? 2. String、StringBuilder、StringBuffer的区别是什么? 3. ==与equals的区别是什么? 4. 什么是反射? 5. Java支持多继承吗? 6. 进程和线程的区别是什么? 7. 不考虑数据库的隔离性会发生什么? 8. 数据库的隔离级别有哪些? 9. 面向对象的三个基本特征是什么? 10. 访问修饰符public、private、protected以及不写时的区别是什么? 11. 给出一些代码块,判断是否能正常编译和执行。 12. 给出一些代码块,预测输出结果。 13. 如何用最有效率的方法计算2乘以8? 14. &和&&的区别是什么? 15. String是Java基本数据类型吗? 16. String类可以继承吗? 以上是一些Java基础高频面试题的例子,希望对你有帮助。 #### 引用[.reference_title] - *1* [Java基础高频面试题](https://blog.csdn.net/qsw1364941774/article/details/124499655)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Java高频面试题及答案整理(会持续更新)](https://blog.csdn.net/qq_44867340/article/details/112879620)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [【吐血整理】2022年Java 基础高频面试题及答案(收藏)](https://blog.csdn.net/m0_67698950/article/details/126549157)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

未禾

您的支持是我最宝贵的财富!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值