java面试题-泛型异常反射
泛型
1.什么是泛型?
Java是一种强类型语言,数据类型在编译时必须确定。如果我们想要在代码中使用不同类型的数据,那么就需要为每种类型分别写出相应的代码。这样会导致代码冗长、重复,也不便于维护。为了解决这个问题,Java引入了泛型机制,允许在类、接口、方法中使用类型参数,使代码更加通用、简洁、安全。
示例代码:
// 不使用泛型
List list = new ArrayList();
list.add("hello");
String str = (String) list.get(0); // 需要强制类型转换,容易出现类型转换异常// 使用泛型
List<String> list = new ArrayList<String>();
list.add("hello");
String str = list.get(0); // 不需要强制类型转换,类型安全
2.泛型类如何定义使用?
泛型类定义的语法格式如下:
public class 类名<类型参数列表> {// 成员变量、方法等
}
其中,类型参数列表是用尖括号包围起来的一组类型参数,可以有多个,用逗号隔开。类型参数可以在类中的任何位置使用。泛型类的实例化时需要指定类型实参。
示例代码:
public class ClassName<T> {private T value;public ClassName(T value) {this.value = value;}public T getValue() {return value;}
}ClassName<Integer> obj = new ClassName<Integer>(123);
int value = obj.getValue();
3.泛型接口如何定义使用?
泛型接口定义的语法格式如下:
public interface 接口名<类型参数列表> {// 方法声明
}
其中,类型参数列表和泛型类的类型参数列表语法相同,可以在接口中的任何位置使用。泛型接口的实现类需要指定类型实参。
public interface InterfaceName<T> {void doSomething(T parameter);
}InterfaceName<String> obj = new InterfaceName<String>() {public void doSomething(String parameter) {System.out.println(parameter);}
};
obj.doSomething("hello");
4.泛型方法如何定义使用?
泛型方法定义的语法格式如下:
修饰符 <类型参数列表> 返回值类型 方法名(形参列表) {// 方法体
}
其中,类型参数列表和泛型类、泛型接口的类型参数列表语法相同,可以在方法中的任何位置使用。在方法调用时,可以显式指定类型实参,也可以通过参数类型推断省略类型实参。
public class ClassName {public <T> void methodName(T parameter) {System.out.println(parameter);}
}ClassName obj = new ClassName();
obj.<String>methodName("hello");
5.泛型的上限和下限?
泛型的上限和下限是限制类型参数的边界。泛型的上限使用 extends 关键字,表示类型参数必须是指定的类型或其子类。泛型的下限使用 super 关键字,表示类型参数必须是指定的类型或其超类。
// 上限
public class ClassName {public <T extends Number> void methodName(T parameter) {System.out.println(parameter);}
}ClassName obj = new ClassName();
obj.methodName(123); // OK
obj.methodName("hello"); // 编译错误,String不是Number的子类// 下限
public void methodName(List<? super Integer> parameter) {parameter.add(123);parameter.add(3.14); // 编译错误,3.14是double类型
}List<Number> list1 = new ArrayList<Number>();
methodName(list1); // OK
List<Object> list2 = new ArrayList<Object>();
methodName(list2); // 编译错误,Object不是Integer或Integer的超类
6.如何理解Java中的泛型是伪泛型?
Java中的泛型是通过类型擦除实现的,即在编译时擦除类型信息,在运行时不保留类型信息。因此,在运行时无法获得泛型类型参数的具体类型。这样,Java中的泛型就成了一种“伪泛型”。泛型类型信息在编译时可以检查,但在运行时被擦除,这是泛型机制的一个局限性,但也是Java泛型的一个优点,因为这种方式避免了运行时的类型转换错误,并提高了运行时的性能。
另外,Java中的泛型还存在一个“类型擦除”问题。在使用泛型时,类型参数实际上被转换成了其边界类型或 Object 类型。这就导致了一些限制,比如无法创建泛型数组,无法在泛型类型中使用基本类型等。虽然Java中的泛型有一些限制,但仍然是一种非常有用的机制,可以使代码更加通用、简洁、安全。
public class ClassName<T> {private T value;public ClassName(T value) {this.value = value;}public T getValue() {return value;}
}ClassName<Integer> obj1 = new ClassName<Integer>(123);
ClassName<String> obj2 = new ClassName<String>("hello");System.out.println(obj1.getClass().getName()); // ClassName
System.out.println(obj2.getClass().getName()); // ClassName// 泛型类型信息在运行时被擦除
异常
1.Java异常类层次结构?
Java异常类层次结构是异常处理的基础,如下所示:
java.lang.Object|+--java.lang.Throwable|+--java.lang.Error|+--java.lang.Exception|+--java.io.IOException|+--java.sql.SQLException|+--其他异常类
所有的异常类都继承自 Throwable 类。Throwable 类有两个直接子类:Error 和 Exception。Error 表示系统级别的错误和资源耗尽等无法恢复的错误,程序通常无法处理。例如,OutOfMemoryError 表示内存不足错误。Exception 是程序中可能会遇到的异常情况,程序可以通过捕获和处理这些异常来恢复正常运行。Exception 又分为可查的异常(checked exceptions)和不可查的异常(unchecked exceptions)。可查的异常是指在编译时必须进行处理的异常,这些异常必须被捕获或声明抛出。不可查的异常是指在编译时无法确定是否需要处理的异常,这些异常不需要被捕获或声明抛出。
2.可查的异常(checked exceptions)和不可查的异常(unchecked exceptions)区别?
可查的异常必须在编译时进行处理,否则编译器会报错。这些异常通常是由系统或程序逻辑错误引起的,例如文件不存在、输入输出错误等。常见的可查异常包括 IOException、SQLException 等。
不可查的异常通常是由程序设计错误引起的,例如空指针异常、类型转换异常等。这些异常通常发生在运行时,编译器无法检测到。不可查的异常不需要在方法签名中声明抛出,并且不需要在调用时进行处理。
3.throw和throws的区别?
throw 和 throws 关键字都用于处理异常,但含义不同。throw 关键字用于抛出一个异常对象。在方法中,当程序发现异常情况时,可以使用 throw 关键字抛出一个异常对象。例如:
if (x == null) {throw new NullPointerException("x is null");
}
throws 关键字用于在方法签名中声明可能抛出的异常。在方法中,如果可能会抛出一个异常,但是不想在方法内部进行处理,可以在方法签名中使用 throws 关键字声明可能抛出的异常。例如:
public void foo() throws Exception {// 方法体
}
4.Java 7 的 try-with-resources?
Java 7 引入了 try-with-resources 语句,这是一种简化关闭资源代码的方法。在 try-with-resources 语句中,可以自动关闭实现了 java.lang.AutoCloseable 接口的资源,例如文件或数据库连接等。
以下是一个使用 try-with-resources 语句的简单示例:
public class Demo {public static void main(String[] args) {try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {String line = reader.readLine();while (line != null) {System.out.println(line);line = reader.readLine();}} catch (IOException e) {e.printStackTrace();}}
}
在上面的示例中,BufferedReader 和 FileReader 都实现了 AutoCloseable 接口。在 try-with-resources 语句中,我们创建一个 BufferedReader 对象和一个 FileReader 对象,并将它们作为资源传递给 try 语句。当程序离开 try 块时,JVM 会自动关闭这两个资源。
try-with-resources 语句可以有多个资源,例如:
try (Resource1 res1 = new Resource1(); Resource2 res2 = new Resource2()) {// ...
}
在这种情况下,两个资源都会被自动关闭。如果资源之间有依赖关系,可以按照需要在 try-with-resources 语句中创建和关闭资源。
5.Java 异常的底层实现,以及Exception Table是什么?
Java 异常的底层实现涉及到 Java 虚拟机(JVM)中的 Exception Table。在 Java 代码编译成字节码时,编译器会将所有可能抛出异常的代码块标记为异常处理器。这些异常处理器被编译器放在 Exception Table 中,并包含了异常处理器的入口地址、代码块的起始和结束位置、以及异常类型等信息。
当程序执行到可能抛出异常的代码块时,JVM 会检查 Exception Table 中是否存在与当前抛出的异常匹配的异常处理器。如果存在,则将程序控制流转移到对应的异常处理器,执行异常处理器中的代码。如果不存在匹配的异常处理器,则将异常抛出到调用栈上层的异常处理器或者 JVM 运行时系统中进行处理。
下面是一个简单的示例,用于演示 Exception Table 的实现:
public class Demo {public static void main(String[] args) {int result = divide(10, 0);System.out.println("Result: " + result);}public static int divide(int a, int b) {int result = 0;try {result = a / b;} catch (ArithmeticException e) {System.out.println("Exception caught: " + e.getMessage());}return result;}
}
在上面的示例中,divide() 方法计算两个整数的商。如果除数为 0,则会抛出一个 ArithmeticException 异常。在 main() 方法中,调用 divide() 方法计算结果,并打印计算结果。
当执行到 result = a / b 语句时,JVM 会检查 Exception Table 中是否存在匹配 ArithmeticException 异常的异常处理器。在这个示例中,存在一个匹配的异常处理器,它位于 catch (ArithmeticException e) 代码块中。JVM 将程序控制流转移到异常处理器中,并执行其中的代码,打印异常信息。然后,JVM 将程序控制流返回到调用 divide() 方法的地方,继续执行程序。
反射
什么是反射?
反射是一种在运行时动态地获取类的信息和调用类的方法的能力。Java 反射 API 可以让程序在运行时动态地创建对象、访问对象属性、调用对象方法以及获取对象信息等,从而增强了程序的灵活性和可扩展性。

2.反射的使用?
反射可以用来实现一些高级的特性,比如依赖注入、框架配置和代理等。反射 API 主要提供了以下几个类来实现反射功能:
Class 类:表示一个类的类型,可以用来获取类的信息、实例化对象、访问类的静态成员和调用类的方法等。
Field 类:表示一个类的字段,可以用来访问和修改对象的属性。
Method 类:表示一个类的方法,可以用来调用对象的方法。
Constructor 类:表示一个类的构造函数,可以用来实例化对象。
下面是一个简单的示例,用于演示反射的使用:
public class Demo {private String message;public Demo(String message) {this.message = message;}public String getMessage() {return message;}
}public class Main {public static void main(String[] args) throws Exception {Class<?> cls = Class.forName("Demo");Constructor<?> constructor = cls.getConstructor(String.class);Object obj = constructor.newInstance("Hello, world!");Method method = cls.getMethod("getMessage");String message = (String) method.invoke(obj);System.out.println(message);}
}
在上面的示例中,Demo 类有一个带有一个参数的构造函数和一个返回 message 属性值的 getMessage() 方法。在 Main 类中,使用 Class.forName() 方法获取 Demo 类的类型,然后使用 getConstructor() 方法获取 Demo 类的带有一个字符串参数的构造函数。接着,使用 newInstance() 方法创建一个 Demo 类的实例。最后,使用 getMethod() 方法获取 Demo 类的 getMessage() 方法,然后使用 invoke() 方法调用该方法,并将返回值强制转换为字符串类型。
3.getName、getCanonicalName与getSimpleName的区别?
这三个方法都是在 Class 类中定义的,可以用来获取一个类的名称或规范化名称。在很多情况下,它们的返回值是相同的。但是,在一些特殊情况下,它们的返回值可能会有所不同。
getName() 方法返回的是一个类的全限定名,包括包名和类名,例如 "java.lang.String"。
getCanonicalName() 方法返回的是该类的规范化名称,也就是在所有类型名称上执行一系列规则后的名称,例如 "java.lang.String"。
getSimpleName() 方法返回的是该类的简单名称,也就是不包括包名的类名,例如 "String"。
相关文章:

java面试题-泛型异常反射
泛型1.什么是泛型?Java是一种强类型语言,数据类型在编译时必须确定。如果我们想要在代码中使用不同类型的数据,那么就需要为每种类型分别写出相应的代码。这样会导致代码冗长、重复,也不便于维护。为了解决这个问题,Ja…...

详细解读ChatGPT:如何调用ChatGPT的API接口到官方例子的说明以及GitHub上的源码应用和csdn集成的ChatGPT
文章目录1. 解读ChatGPT1.1 词语解释1.2 功能解读2. GitHub上ChatGPT的应用源码3. 调用ChatGPT的API4. 官方例子说明5. 集成ChatGPT自ChatGPT出来到如今,始终走在火热的道路上,如今日活用户破亿,他为何有如此大的魅力,深受广大用户…...

九龙证券|最新评级情况出炉,机构扎堆这一板块!聚氨酯龙头获得最多关注
本周算计254家上市公司获组织“买入型”评级。 电子板块评级组织扎堆 证券时报数据宝计算,2月13日至17日,A股市场53家组织算计进行347次评级,254家上市公司获“买入型”评级(包含买入、增持、强烈推荐、推荐)。 从申…...

考研复试机试 | C++ | 尽量不要用python,很多学校不支持
目录1.1打印日期 (清华大学上机题)题目:代码:1.2改一改:上一题反过来问题代码:2.Day of Week (上交&&清华机试题)题目:代码:3.剩下的树(清…...

ChatGPT时代,别再折腾孩子了
今天这篇完全是从两件事儿有感而发。昨天在文印店,在复印机上看到装订好的几页纸,我瞥了一眼,是历史知识点:隋朝大运河分为四段,分别是___ ___ ___ ___,连接了五大河___ ___ ___ ___ ______ 年ÿ…...

万字干货 | 荔枝魔方基于云原生的架构设计与实践
近年来,荔枝集团在国内和海外的业务迅速发展,业务数据规模也是成几何式地增长,海量数据的计算分析场景、业务智能算法应用需求随之而生,为了快速地满足业务发展的需要,我们面临着诸多的技术挑战。技术挑战工程问题资源…...
#科研筑基# python初学自用笔记 第九篇 面向对象编程
面向对象编程 Object Oriented Programming ,简称OOP,是一种程序设计思想,这种思想把对象作为程序的基本单元。类是抽象的,对象是具体的,一种类包括其特定的数据或属性,以及操作数据的函数(方法…...

Python快速上手系列--邮件发送--详解篇
本章就来一起学习一下跑完自动化脚本后如何自动的发送邮件到指定的邮箱。zmail操作:1. 导包 import zmail2. 邮件内容,包含:主题(subject)、正文(content_text)、附件(attachments)3. 发件人信息,包含:发件人账号&…...

【Bluetooth开发】蓝牙开发入门
BLE 蓝牙设备在生活中无处不在,但是我们也只是将其作为蓝牙模块进行使用,发送简单的AT命令实现数据收发。 那么,像对于一些复杂的使用场合:“车载蓝牙”、"智能手表"、“蓝牙音箱”等,我们不得不去了解底层…...
07:进阶篇 - 在程序中嵌入 CTK Plugin Framework
作者: 一去、二三里 个人微信号: iwaleon 微信公众号: 高效程序员 如果已经创建了一个应用程序,现在要将 CTK Plugin Framework 嵌入其中,该如何进行呢? 下面,以《06:进阶篇 - Hello,CTK!》中的插件为例,来演示如何使用 CTK Plugin Framework 来加载插件并获取特定…...
快速低成本动画视频课
快速低成本动画视频课Character Animator能做什么如何用character animator制作动画视频Animate能做什么Adobe Animate和Character Animator结合,如何快速制作低成本动画视频课Character Animator能做什么 Character Animator是Adobe公司的一个动画制作软件&#x…...
大数据平台测试-软件测试常见面试回答(持续更新)
面试造航母,入职拧螺丝。面试,讲点面试官想听的。。。 1、你有过漏测的经历吗? 答:这道题肯定是回答有。然后展开描述。就类似面试官问 你印象比较深的一个bug。。。 测试无穷尽,质量也并非测试一个岗位的责任&…...
链表学习之反转链表
链表解题技巧 额外的数据结构(哈希表);快慢指针;虚拟头节点; 反转链表 分别实现单向链表和双向链表的反转。 要求:长度为N的链表,时间复杂度为O(N),额外空间复杂度为O(1)。 反转…...

ONNXRUNTUIME实例分割网络说明
ONNXRUNTUIME c使用(分割网络)与相关资料(暂记) initiate a env with an id name(使用id名称启动env) create session (创建会话 ) onnxenv -> sessioninputname [“x”] ,outputname [“t”]inputnodedim [[1,1,192,192…...

几行代码,就写完懒加载啦?
Ⅰ、前言 「懒加载」是网页中非常 常见的;为了减少系统的压力,对于一些电商系统出场频率非常高;那么大家一般用什么方式去实现 「懒加载」 呢 ? ① 通过 scroll 的形式: 通过 滚动「scroll」事件,然后去判…...

PyTorch常用的损失函数(ChatGPT)
L1Loss nn.L1Loss 也称为平均绝对误差(Mean Absolute Error,MAE)。它计算预测值与真实值之间的差异(即误差),然后取绝对值并求和,最后除以样本数量得到平均误差。具体来说,对于一批…...

LeetCode——1237. 找出给定方程的正整数解
一、题目 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/find-positive-integer-solution-for-a-given-equation/description/ 翻译一下题目 意思是,这是一个二维单调递增的函数,函数一共有 9 …...

系统编程中的进程的概念No.3【进程状态】
引言: 北京时间:2023/2/17/8:17,目前听着超能陆战队主题曲《Immortals》,感觉又要螺旋式升天,并且为我今天上午没课感到happy,所以继我们很久以前的关于进程的博客,今天我们就再来学习一下有关…...
推荐 3 款 Golang 语义化版本库
文章目录1.什么是语义化版本 2.0.02.Golang 语义化版本库比较3.小结参考文献1.什么是语义化版本 2.0.0 语义化版本 2.0.0(Semantic Versioning 2.0.0)是一种用于标识软件版本的约定和规范。它包含三个数字组成的版本号,格式为“MAJOR.MINOR.…...

Windows平台使用gdb连接qemu虚拟机上的系统
先安装MinGW; 除了gcc、g,把gdb也选上;可能选第一个就可以了,不清楚把后面几个也选上; 安装完成看一下gcc, g,gdb,编译工具和调试器都有了; 把bin目录加到环境变量; 看一…...

css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
【Java学习笔记】BigInteger 和 BigDecimal 类
BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点:传参类型必须是类对象 一、BigInteger 1. 作用:适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...

基于江科大stm32屏幕驱动,实现OLED多级菜单(动画效果),结构体链表实现(独创源码)
引言 在嵌入式系统中,用户界面的设计往往直接影响到用户体验。本文将以STM32微控制器和OLED显示屏为例,介绍如何实现一个多级菜单系统。该系统支持用户通过按键导航菜单,执行相应操作,并提供平滑的滚动动画效果。 本文设计了一个…...

AD学习(3)
1 PCB封装元素组成及简单的PCB封装创建 封装的组成部分: (1)PCB焊盘:表层的铜 ,top层的铜 (2)管脚序号:用来关联原理图中的管脚的序号,原理图的序号需要和PCB封装一一…...

SFTrack:面向警务无人机的自适应多目标跟踪算法——突破小尺度高速运动目标的追踪瓶颈
【导读】 本文针对无人机(UAV)视频中目标尺寸小、运动快导致的多目标跟踪难题,提出一种更简单高效的方法。核心创新在于从低置信度检测启动跟踪(贴合无人机场景特性),并改进传统外观匹配算法以关联此类检测…...

本地部署drawDB结合内网穿透技术实现数据库远程管控方案
文章目录 前言1. Windows本地部署DrawDB2. 安装Cpolar内网穿透3. 实现公网访问DrawDB4. 固定DrawDB公网地址 前言 在数字化浪潮席卷全球的背景下,数据治理能力正日益成为构建现代企业核心竞争力的关键因素。无论是全球500强企业的数据中枢系统,还是初创…...