java面试题(二)

发布于:2025-07-27 ⋅ 阅读:(18) ⋅ 点赞:(0)

11. Java 反射获取类信息的方式有哪几种?分别是什么?​

反射获取类信息(Class对象)的方式有 3 种:​

  1. Class.forName(String className):​

通过类的全限定名加载类(触发类初始化),如Class.forName("java.lang.String")。​

  1. 对象.getClass():​

通过实例对象获取Class,如"hello".getClass()。​

  1. 类名.class:​

直接通过类名获取(不触发类初始化),如String.class。​

12. Java 代理的主要方法有哪几种?列举代理的使用场景 2 个。​

主要代理方法​

  1. 静态代理:​

手动编写代理类(实现与目标类相同的接口),在代理类中调用目标方法并添加增强逻辑(如日志)。缺点:代理类与目标类耦合,不易扩展。​

  1. 动态代理:​
  • JDK 动态代理:基于接口生成代理类(通过Proxy.newProxyInstance()),要求目标类实现接口;​
  • CGLIB 动态代理:通过继承目标类生成代理子类(无需接口),基于 ASM 字节码技术。​

使用场景​

  • AOP(面向切面编程):如 Spring AOP 通过代理实现日志、事务、权限等横切逻辑;​
  • 远程调用:如 RPC 框架(Dubbo)通过代理封装网络通信细节,让调用远程服务像调用本地方法。​

13. equals () 方法的作用是什么?重写 equals 需要注意哪些事项?为什么?​

  • 作用:判断两个对象的内容是否相等(==判断地址是否相等)。​

重写equals的注意事项(需满足 5 大特性)​

  1. 自反性:x.equals(x)必须返回true;​
  1. 对称性:x.equals(y)与y.equals(x)结果一致;​
  1. 传递性:若x.equals(y)且y.equals(z),则x.equals(z);​
  1. 一致性:多次调用结果相同(对象未被修改时);​
  1. 与hashCode()一致:若x.equals(y)为true,则x.hashCode()必须等于y.hashCode()。​

原因​

  • 违反前 4 点会导致逻辑错误(如集合中判断元素相等时出错);​
  • 违反第 5 点会导致HashMap、HashSet等基于哈希的集合无法正常工作(如两个相等的对象可能被存入不同桶中)。​

14. Java 是按值传递还是按引用传递?什么是引用传递,什么是值传递,哪些语言支持引用传递?​

  • Java 是按值传递:​
  • 基本类型:传递值的副本(修改副本不影响原变量);​
  • 引用类型:传递引用地址的副本(修改副本指向的对象内容会影响原对象,但修改副本的指向不影响原引用)。​

概念区分​

  • 值传递:传递数据的副本,函数内修改副本不影响原数据;​
  • 引用传递:传递数据的地址(而非副本),函数内修改会直接影响原数据。​

支持引用传递的语言​

如 C++(通过&声明引用参数)、Python(对象传递本质是引用传递)。​

15. 描述 java 的类初始化顺序?如果存在继承,初始化顺序会如何​

单个类的初始化顺序(从先到后)​

  1. 静态变量(类变量);​
  1. 静态代码块(static {});​
  1. 实例变量(成员变量);​
  1. 构造代码块({},每次创建实例时执行);​
  1. 构造方法。​

存在继承时的初始化顺序​

  1. 父类静态成员 / 静态代码块(只执行一次);​
  1. 子类静态成员 / 静态代码块(只执行一次);​
  1. 父类实例成员 / 构造代码块;​
  1. 父类构造方法;​
  1. 子类实例成员 / 构造代码块;​
  1. 子类构造方法。​

规律:静态优先于实例,父类优先于子类。​

16. 本地方法栈有什么作用?​

本地方法栈是 JVM 内存区域之一,作用是:​

  • 支持本地方法(native修饰的方法) 的执行,存储本地方法的参数、返回值、局部变量等;​
  • 本地方法通常用 C/C++ 实现,本地方法栈与操作系统的栈结构相关(不同系统实现不同)。​

17. 描述 Java 的双亲委派机制,为什么要用到双亲委派机制​

  • 双亲委派机制:类加载时,子类加载器先委托父类加载器加载类,若父类加载器无法加载(找不到类),子类加载器才尝试自己加载。​

核心加载器(从父到子)​

  • 启动类加载器(Bootstrap):加载JAVA_HOME/lib下的核心类(如java.lang.String);​
  • 扩展类加载器(Extension):加载JAVA_HOME/lib/ext下的类;​
  • 应用类加载器(App):加载应用 classpath 下的类。​

作用​

  1. 避免类重复加载:同一类只会被一个加载器加载;​
  1. 保证核心类安全:防止自定义类(如java.lang.String)篡改核心类,避免安全风险。​

18. 重写和重载的区别是什么?​

维度​

重写(Override)​

重载(Overload)​

定义​

子类覆盖父类的方法​

同一类中方法名相同,参数不同​

方法名​

必须相同​

必须相同​

参数列表​

必须相同(个数、类型、顺序)​

必须不同(个数、类型、顺序)​

返回值类型​

子类返回值需与父类兼容(<= 父类)​

可不同​

访问修饰符​

子类修饰符权限 >= 父类​

无限制​

异常​

子类抛出异常 <= 父类​

无限制​

作用​

实现多态(运行时绑定)​

提高方法灵活性(编译时绑定)​

19. 子类构造方法调用父类构造方法的注意事项有哪些?​

  1. 默认调用父类无参构造:子类构造方法第一行隐含super(),若父类无无参构造,编译报错;​
  1. 显式调用父类有参构造:若父类只有有参构造,子类必须在构造方法第一行用super(参数)显式调用;​
  1. 不可调用多次:super()或this()(调用本类其他构造方法)只能出现一次,且必须在第一行。​

20. 子类实例初始化是否触发父类实例初始化?​

是。​

子类实例化时,会先执行父类的实例初始化(实例变量、构造代码块、构造方法),再执行子类的实例初始化。原因是:子类构造方法第一行会调用父类构造方法(super()),触发父类实例初始化。​


网站公告

今日签到

点亮在社区的每一天
去签到