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

Java面试(基础篇) - 第二篇!

未看第一篇的,这里可以直达
Java面试(基础篇) - 第一篇

Integer对象可以用==判断吗?为什么?

回答

不可以,因为 == 比较的是对象的实例(内存地址),Integer是有一个缓存机制的,它会将-128–127之间的数字缓存下,所以,我们使用 == 比较,在这个数字区间内,它是相等的。但是,如果超过了这个区间,他就不相等了。所以,建议还是使用equals方法比较。

扩展

测试一下 看看代码

        Integer a=10;Integer b=10;System.out.println(a==b);//trueInteger c=128;Integer d=128;System.out.println(c==d);//falseSystem.out.println(c.equals(d));//true

Java为什么不支持多继承?

回答

如果支持多继承 就会产生菱形继承问题。即,
在这里插入图片描述
Parrot无法确定是从Bird 还是Mammal继承Animal的方法。
其次,如果支持多继承,Java中的复杂度也会上升,不利于维护。修改一个父类,可能会影响多个子类,增加代码的复杂度。
Java中 是通过接口实现 来达到多继承的效果的。

扩展

这个问题,java之父,James Gosling也曾回答过,就是因为会产生菱形继承问题。
此外 Java提供了另一种方式,即多实现接口 来达到同样的效果。
那么,新问题,实现的两个接口中,有一个方法名,参数相同的方法,此时继承类要实现哪一个?
答案是,会编译报错,此时,这个问题就交给开发人员去解决。进行重写这个方法。

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

回答

接口和抽象类都可以代表抽象层,只不过说,两者的含义不一样。接口更多用于制定规范,抽象类则用于复用。

另外,抽象类可以有构造器,接口没有。虽然说 抽象类不能直接new,但是抽象类的构造器也可以作为初始化赋值来用。
接口在java8之前,只能定义,并且默认修饰符public,不能用其他修饰符,而抽象类则可以有具体的方法实现。

扩展

说到接口和抽象类的区别,我们可以通过模板方法来深入理解一下。
模板方法作为一种设计模式,它主要就是为了解决代码中的复用问题。


public abstract class Coupon {public final void applyCoupon() {//打印是否有效invalidCoupon();//打印折扣applyDisCount();}//具体折扣逻辑protected abstract void applyDisCount();//无效优惠卷逻辑protected abstract void invalidCoupon();
}
public class FixedAmountCoupon extends Coupon{@Overrideprotected void applyDisCount() {System.out.println("满100减10");}@Overrideprotected void invalidCoupon() {System.out.println("无效优惠卷");}
}
public class PercentageCoupon extends Coupon{@Overrideprotected void applyDisCount() {System.out.println("打八折");}@Overrideprotected void invalidCoupon() {System.out.println("无效优惠卷");}
}public static void main(String[] args) {Coupon fixedAmountCoupon = new FixedAmountCoupon();fixedAmountCoupon.applyCoupon();}

如何理解Java中的多态?

回答

统一操作针对不同的对象,得到不同的结果。在Java中,子类重写父类的方法,就是多态的一种体现。
满足三个条件即可。
类继承或实现方法。
子类重写父类的方法。
父类的指针指向子类的引用。

扩展

多态是一种运行期的概念,有人说多态分为两种,静态多态和动态多态。静态多态就是重载,编译器实现方法名相同,参数类型个数不同。不过我认为 多态是一种运行期的概念,重写更能体现。

有了基本数据类型 为什么还要使用包装类?

回答

因为,Java是面向对象的语言,很多地方要求使用对象。比如说集合,泛型。
另外,包装类也提供了一些方法,可以直接使用,便于开发。

扩展

如果包装类Integer 和基本数据类型int进行数据比较,是int转为Integer 还是Integer 转为int呢?
实际上,不管是包装类和基本类比较,还是包装类和包装类比较,都是转为int,底层使用intValue这个方法进行比较的。

可以使用浮点数表示金额计算吗?为什么?

回答

不可以,不是所有的小数都可以用浮点数来表示的。IEEE提出用近似值表示小数,并且引入了精度的概念,这就是我们所说的浮点数。浮点数只是近似值,而不是精确值,所以不能用来表示金额,否则精度会缺失。

扩展

不是所有的数都可以用二进制表示的,比如0.1,转化为二进制就会出现无限循环的情况。
为了解决精度问题,Java提供了BigDecimal来进行精确运算。

可以使用BigDecimal的equals进行等值比较吗?为什么?

回答

不可以,equals比较是两部分,值和标度,对于0.1和0.10这两个数,虽然他们的值相同,但他们的标度不同,所以也不相等。

扩展

BigDecimal 提供了四种类型的接收,int,long,double,String。其中int 和long是整数,所以他们的标度是0,而对于
double,使用new BigDecimal(0.1)创建的时候,实际上我们拿到的是0.1的近似值,也就是一个55位的小数。标度为55.
而我们使用new Bigdecimal(“0.1”)的时候,值是01.而标度则是1.

对于比较BigDecimal,推荐的做法是 使用CompareTo方法,这个方法只比较两个数字的值,不比较标度,相等则返回0.

Java中负数取绝对值,结果一定是正数吗?

回答

不一定,Math.abs(),这里要是取到了Integer的最小值,取绝对值出来,还是一个负数。这是因为,此时这个最小数已经是Int类型的最小数了,再去拿绝对值,就会发生越界。超出int的范围。

System.out.println(Math.abs(Integer.MIN_VALUE));

如何解决呢,只需要将他转为Long类型即可。

System.out.println(Math.abs((long)Integer.MIN_VALUE));

扩展

我们直到Java中的基本数据类型中的整型有 byte,short,int,long四种。数字的范围也是从小到大的。1byte=1个字节。范围是,-2^7 ~2^7-1.也就是-128到127。初始化时,byte默认值是0.short则使用两个字节存储,范围是-32768 - 32767 (-2^15 ~ 215-1).int则是四个字节存储,-231 ~ 2^31-1.long 则是八个字节 范围为-2^63 ~ 2 ^63-1。
超出范围,就会发生溢出,溢出并不会抛出异常,已没有任何提示,所以在进行数据运算的时候,一定要注意。

什么是泛型?为什么要用泛型?

回答

泛型是JDK5引入的概念,允许在定义类或者接口的时候,使用类型参数。声明的类型参数在使用时用具体的类型来替换。
好处就是,提高了代码的复用性,以及安全性。在泛型出来之前,做类型转换的时候,要进行类型检查,如果类型转换出错,就会直接宕掉。而泛型的作用就是在编译时,进行类型检查,增加程序的安全性。

扩展

举个例子看一下,如何定义一个简单的泛型。

  public static void main(String[] args) {List<String> listString = new ArrayList<>();listString.add("1");String first = getFirst(listString);List<Integer> listInteger = new ArrayList<>();Integer first1 = getFirst(listInteger);System.out.println(first1);}//定义一个静态方法 传入List<?> 泛型 返回对应类型的第一个数据,没有数据则返回nullpublic static <T> T getFirst(List<T> list){if(list.size() == 0){return null;}return list.get(0);}

可以看到 这里我传入是String类型,它就会返回String类型的参数。如果是Integer类型,则会返回Integer类型的参数。如此,就可以实现,一个方法,多种类型都可以使用,增加了代码的复用性。

了解过类型擦除吗?为什么要进行类型擦除?

回答

简单理解就是 将泛型Java代码转化为普通Java代码。不过编译器更直接点,将泛型Java代码转为字节码。

所谓的类型擦除 就是将泛型信息擦除掉 转为使用Object对象接收。这也是为什么要使用包装类的一个原因。基本数据类型非对象,不进行装箱,无法使用泛型。

扩展

泛型中用于定义的字母,主要有K T V E Object。
E主要在集合中使用,代表的是元素。
T则主要代表Java类,如我们自定义的User类,就可以用T代替。
K V 指的是键值
N代指数据类型。
? 则表示不确定的Java类型。
Object 代指所有类的根类,任何类的对象,都可以设置为Object的引用变量,使用时进行强制类型转换即可。

泛型中的上下界限定符extends supper区别是什么?

回答

一般我们认为,extends代表的是类型的上界,也就是参数只能传它本身或者它的子类。比如,我们有一个people类,teacher 和 student都是它的子类。 使用Student 就可以正常调用方法,但是如果传入一个没有继承People的User,则在编译期就会报错。

 public static void main(String[] args) {Student people = getPeople(new Student());getPeople(new User());}//定义一个静态方法 传入List<?> 泛型 返回对应类型的第一个数据,没有数据则返回nullpublic static <T extends People> T getPeople(T t){return t;}

了解了泛型中的上界限定符,我们再来看一下下界限定符,其实它的作用和上界限定符刚好相反。表示,参数化类型必须是此类或者此类的父类。

 public static void main(String[] args) {test(new ArrayList<People>());test(new ArrayList<Student>());test(new ArrayList<Teacher>());}//定义一个静态方法 演示下界限定符 使用Student类 他的父类是People public static <T> T test(List<? super Student> t) {return null;}

扩展

使用限定通配符 我们需要遵守PECS原则。即,上界生产,下界消费。

如果 需要向集合读取,就可以使用 ?extends 通配符。我们认为,从集合中读 集合就是生产者。

如果不需要读,只要写入,那就可以使用? supper通配符。

如果 即要存又要取 那就不要使用任何限定符。

http://www.xdnf.cn/news/1135963.html

相关文章:

  • 2020717零碎写写
  • 91套商业策划创业融资计划书PPT模版
  • Matlab2025a软件安装|详细安装步骤➕安装文件|附下载文件
  • IDEA运行Tomcat一直提示端口被占用(也查不到该端口)
  • 社区搜索离线回溯系统设计:架构、挑战与性能优化|得物技术
  • 在开关电源电路中,WD0407 可作为整流二极管使用,WD0407 40V 7A
  • 前端-列表fixed冻结的列 横向滚动条拖不动
  • NTC电阻防浪涌介绍
  • Linux内核网络栈深度剖析:inet_connection_sock.c的服务器端套接字管理
  • Flutter:上传图片,选择相机或相册:wechat_assets_picker
  • 【软件开发】Copilot 编码插件
  • 【网易云-body1】
  • TRAE IDE** 下载、安装、开发、测试和部署 2048 小游戏的全流程指南
  • 界面控件Kendo UI for Angular 2025 Q2新版亮点 - 增强跨设备的无缝体验
  • 杨耀东老师在ICML2025上对齐教程:《语言模型的对齐方法:一种机器学习视角》
  • 《工程伦理》分析报告五 软件开发
  • Vue3入门-计算属性+监听器
  • Vmware虚拟机使用仅主机模式共享物理网卡访问互联网
  • 时序数据库选型指南 —— 为什么选择 Apache IoTDB?
  • Linux中的数据库操作基础
  • ros2 标定相机
  • Qwen3-8B Dify RAG环境搭建
  • 2D视觉系统标定流程与关键要求
  • 高光谱相机(Hyperspectral Camera)
  • 【后端】Linux系统发布.NetCore项目
  • 尺寸标注识别3 实例分割 roboflow
  • NumPy, SciPy 之间的区别
  • 大语言模型任务分解与汇总:从认知瓶颈到系统化解决方案
  • AutoMQ 与 Lightstreamer 达成战略合作:NASA也在用的 Kafka 数据实时分享新架构
  • 【C# in .NET】16. 探秘类成员-索引器:通过索引访问对象