Java Class 核心面试题及详细答案(实战版)_第1页
Java Class 核心面试题及详细答案(实战版)_第2页
Java Class 核心面试题及详细答案(实战版)_第3页
Java Class 核心面试题及详细答案(实战版)_第4页
Java Class 核心面试题及详细答案(实战版)_第5页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

JavaClass核心面试题及详细答案(实战版)一、基础概念类1.简述Java中Class类的作用,它和普通自定义类有什么区别?参考答案:Class是Java反射机制的核心类,位于java.lang包下,是所有Java类的元数据对象。简单来说,Java中每一个被加载的类、接口、枚举、基本数据类型,在JVM中都会对应一个唯一的Class对象,这个对象用来存储当前类的全部信息,包括类的属性、方法、构造器、注解、父类、接口等。Class类和普通自定义类的核心区别:1.创建方式不同:普通类由开发者new创建实例;Class对象由JVM在类加载阶段自动创建,开发者无法手动newClass()。2.作用不同:普通类用于封装业务数据和业务逻辑,实现具体功能;Class类用于描述、映射已加载的类结构,是反射操作的入口。3.唯一性不同:一个普通类可以new出无数个实例对象;一个类在同一个类加载器下,只会生成一个唯一的Class对象。4.继承关系不同:Class类直接继承自Object,没有父类类;普通自定义类默认继承Object,可自定义继承关系。2.Java中获取Class对象的三种方式,以及各自的使用场景?参考答案:日常开发中共有三种主流获取Class实例的方式,适用场景各不相同:方式1:类名.class(静态获取)语法:Classclazz=User.class;特点:编译期校验,不会触发类的静态代码块执行,性能最高。使用场景:明确知道具体类名,仅需要获取类结构信息,无需创建对象实例的场景。方式2:对象.getClass()(动态获取)语法:Classclazz=user.getClass();特点:运行期获取,基于已有对象实例获取Class对象,会触发类加载。使用场景:已有实例对象,需要动态获取对象所属类的结构信息。方式3:Class.forName("全类名")(反射加载)语法:Classclazz=Class.forName("com.test.User");特点:运行期动态加载类,默认会触发类的静态代码块执行,需要处理类不存在异常。使用场景:不知道具体类名,通过配置文件、字符串动态加载类,典型场景:JDBC驱动加载、框架动态注入类。3.基本数据类型有Class对象吗?包装类和基本类型的Class对象是否一致?参考答案:1.Java八大基本数据类型(byte、short、int、long、float、double、char、boolean)都有对应的Class对象,可通过int.class、boolean.class方式获取。2.基本类型和其对应的包装类的Class对象不相等。示例证明:Integer.class!=int.classInteger是引用类型,对应的Class是普通类对象;int是基本类型,对应的Class是基础类型专属对象,二者在JVM中是两个不同的元数据实例,不能相互等同。二、核心原理与类加载面试题4.同一个类被不同类加载器加载,获取的Class对象是否相等?参考答案:不相等。Java中Class对象的唯一性判定规则:全类名+类加载器共同决定。即使是同一个.class文件,被不同的类加载器加载,会在JVM中生成两个完全独立的Class对象,使用equals()和==判断结果均为false。这也是热部署、模块隔离、容器隔离(Tomcat多项目隔离)的核心原理,不同加载器加载的同名类,相互隔离、互不干扰。5.Class.forName()和ClassLoader.loadClass()的核心区别?参考答案:二者都是动态加载类的方法,核心区别在于类加载阶段的执行程度不同:1.Class.forName()默认执行类加载的全部流程:加载、链接、初始化,会主动执行类的静态代码块、静态变量赋值。日常JDBC加载驱动就是利用这个特性,触发驱动的静态注册代码。2.ClassLoader.loadClass()只执行加载阶段,只会把class文件加载到JVM,不会执行链接和初始化,不会触发静态代码块执行,延迟初始化,性能更优。框架开发中(Spring、MyBatis)大多使用loadClass,避免提前触发类初始化,影响容器Bean管理。6.什么是类的泛型擦除?Class对象为什么无法获取泛型真实类型?参考答案:Java泛型是编译期语法糖,在编译完成后,JVM会将所有泛型标识擦除,这个过程就是泛型擦除。例如List<String>编译后会直接变为List,底层字节码中不保留泛型参数信息。正因为字节码中泛型信息被擦除,普通的Class对象只能记录当前类的基础结构,无法存储运行期泛型参数,所以通过List.class无法获取到String这个真实泛型类型。如果需要获取泛型类型,需要使用ParameterizedType接口,通过反射获取带泛型的父类、接口类型。三、反射实战易错面试题7.通过Class对象可以获取私有属性和方法并调用,是否破坏了Java封装特性?参考答案:不会从语法层面破坏封装,属于运行期绕过语法校验的特殊操作。1.封装的核心目的是编译期代码约束,规范开发者的编码行为,避免随意访问私有成员;2.反射是JVM提供的底层能力,运行期可以无视语法权限修饰符,通过setAccessible(true)解除权限校验,访问私有资源;3.这种操作属于框架底层的拓展能力,日常业务开发不推荐频繁使用,会破坏代码的封装性、可读性和安全性,同时存在性能损耗。8.说说Class对象的常用核心方法(面试高频)参考答案:日常面试和开发中最常用的核心方法如下:1.newInstance():通过无参构造器创建类的实例(JDK9之后废弃,推荐使用getDeclaredConstructor)2.getDeclaredField(Stringname):获取指定字段(包含私有、保护、公共)3.getField(Stringname):仅获取公共public字段4.getDeclaredMethod():获取任意权限的指定方法5.getMethod():仅获取公共public方法6.getSuperclass():获取父类的Class对象7.getInterfaces():获取当前类实现的所有接口Class数组8.isInstance(Objectobj):判断对象是否是当前类的实例,替代instanceof关键字9.数组的Class对象有什么特点?如何判断一个对象是否是数组?参考答案:1.数组也有专属的Class对象,数组的Class对象没有对应的class文件,由JVM动态生成。2.所有一维数组、多维数组的父类都是Object,数组Class对象没有自定义父类。3.判断对象是否为数组,使用Class类的原生方法:clazz.isArray(),不建议通过字符串判断类名。示例:int[].class.isArray()//返回true四、进阶面试真题10.解释Class类的isAssignableFrom()和instanceof的区别?参考答案:两者都是用来判断类型继承关系,核心区别在判断维度和使用场景:1.instanceof是运算符,作用于对象实例,运行期判断某个对象是否属于某个类/接口的实例,包含继承、实现关系,判断的是对象和类的关系。2.isAssignableFrom()是Class类的方法,作用于两个Class对象,判断当前类是否可以接收目标类的赋值,判断的是类与类的继承、父子关系。核心规则:A.class.isAssignableFrom(B.class),判断B是否是A的子类或实现类。简单总结:对象判断用instanceof,类层级判断用isAssignableFrom。11.为什么反射操作效率偏低?Class反射的性能损耗点在哪里?参考答案:反射相比直接new、直接调用方法性能更低,主要损耗点有3个:1.运行期动态解析:普通方法调用编译期就确定地址;反射需要运行期动态解析类

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论