java 基础中
泛型
https://blog.csdn.net/weixin_45630258/article/details/121573687
Java 泛型(generics) 是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
Java 的泛型是伪泛型,这是因为 Java 在运行期间,所有的泛型信息都会被擦掉,这也就是通常所说类型擦除 。
泛型一般有三种使用方式: 泛型类、泛型接口、泛型方法
在实例化泛型类时,必须指定T的具体类型
作用:安全 约束类型
提高性能:类型固定,避免重复的装箱 拆箱
提高方法复用性
场景:
常用的通配符
反射
1. 反射机制的功能
Java反射机制主要提供了以下功能:
- 在运行时判断任意一个对象所属的类。
- 在运行时构造任意一个类的对象。
- 在运行时判断任意一个类所具有的成员变量和方法。
- 在运行时调用任意一个对象的方法。
- 在运行时处理注解
- 生成动态代理。
2. 反射相关API
反射的应用场景
像 Spring/Spring Boot、MyBatis 等等框架中都大量使用了反射机制。这些框架中也大量使用了动态代理,而动态代理的实现也依赖反射。
1)经典的就是在xml文件或者properties里面写好了配置,然后在Java类里面解析xml或properties里面的内容,得到一个字符串,然后用反射机制,根据这个字符串获得某个类的Class实例
,这样就可以动态配置一些东西,不用每一次都要在代码里面去new或者做其他的事情,以后要改的话直接改配置文件,代码维护起来就很方便了,同时有时候要适应某些需求,
Java类里面不一定能直接调用另外的方法,这时候也可以通过反射机制来实现。
2)当你做一个软件可以安装插件的功能,你连插件的类型名称都不知道,你怎么实例化这个对象呢?因为程序是支持插件的(第三方的),在开发的时候并不知道 。所以无法在代码中 New出来 ,但反射可以,通过反射,动态加载程序集,然后读出类,检查标记之后再实例化对象,就可以获得正确的类实例。
3你写了一个程序,这个程序定义了一些接口,只要实现了这些接口的dll都可以作为插件来插入到这个程序中。那么怎么实现呢?就可以通过反射来实现。就是把dll加载进内存,然后通过反射的方式来调用dll中的方法 dll:动态链接库
反射机制的优缺点
反射实战
获取 Class 对象的四种方式
注解
Annontation
(注解) 是Java5 开始引入的新特性,可以看作是一种特殊的注释,主要用于修饰类、方法或者变量。
注解不是必须的
注解本质是一个继承了Annotation
的特殊接口
注解可以被其他程序读取(如编译器)
注解只有被解析之后才会生效,常见的解析方法有两种:
内置注解
override
如重写toString()时,接口名写错了会报错
简述元注解
元注解可以理解为注解的注解,即在注解中使用,实现想要的功能。其具体分为:
- @Retention: 表示注解存在阶段是保留在源码,还是在字节码(类加载)或者运行期(JVM中运行)。描述注解的生命周期
- @Target:表示注解作用的范围。
- @Documented:将注解中的元素包含到 Javadoc 中去。
- @Inherited:一个被@Inherited注解了的注解修饰了一个父类,如果他的子类没有被其他注解修饰,则它的子类也继承了父类的注解。
- @Repeatable:被这个元注解修饰的注解可以同时作用一个对象多次,但是每次作用注解又可以代表不同的含义。
例如 Override.java
自定义注解
异常
Error
无论是受检异常还是非受检异常,都是发生在程序的运行阶段,不要错误地认为编译时异常就发生在编译阶段!!!
Checked Exception 和 Unchecked Exception 有什么区别?
Checked Exception 即受检查异常(编译时异常),Java 代码在编译过程中,如果受检查异常没有被 catch
/throw
处理的话,就没办法通过编译 。
受检异常的处理方法有两种:1.throws抛给上一级处理,2.使用try/catch进行捕捉
Unchecked Exception 即 不受检查异常 (运行时异常),Java 代码在编译过程中 ,我们即使不处理不受检查异常也可以正常通过编译。如如 除以0
String str =null; int num; try { num =Integer.parseInt(str); System.out.println(num); }catch(NumberFormatException e){ System.out.println("不是数字"); }catch(NullPointerException e){ System.out.println("空指针"); }catch (Exception e) { // TODO: handle exception e.printStackTrace(); }finally{ System.out.println("ok"); }
不是数字
ok
try即尝试,尝试能不能正常的走完整个作用域,如果不能则抛出一个异常。所以在try块里经常放上可能会抛出异常的程序段。而catch就是处理try里抛出来的异常,其中catch的参数列表接收的是一个异常的引用,是throw抛出来的异常的引用
try catch是直接处理,处理完成之后程序继续往下执行,throw则是将异常抛给它的上一级处理,程序便不往下执行了。
Throwable 类常用方法有哪些
try-catch-finally 如何使用
注意:不要在 finally 语句块中使用 return!
当 try 语句和 finally 语句中都有 return 语句时,try 语句块中的 return 语句会被忽略。
这是因为 try 语句中的 return 返回值会先被暂存在一个本地变量中,当执行到 finally 语句中的 return 之后,这个本地变量的值就变为了 finally 语句中的 return 返回值
finally 中的代码一定会执行
不一定
finally
之前虚拟机被终止运行
程序所在的线程死亡。
关闭 CPU。
使用 try-with-resources
代替try-catch-finally
- 适用范围(资源的定义): 任何实现
java.lang.AutoCloseable
或者java.io.Closeable
的对象 - 关闭资源和 finally 块的执行顺序: 在
try-with-resources
语句中,任何 catch 或 finally 块在声明的资源关闭后运行
面对必须要关闭的资源,我们总是应该优先使用 try-with-resources
而不是try-finally
。随之产生的代码更简短,更清晰,产生的异常对我们也更有用。
try-with-resources
语句让我们更容易编写必须要关闭的资源的代码,若采用try-finally
则几乎做不到这点。