🌟个人主页:时间会证明一切.
目录
注解的作用是什么
Java 注解用于为 Java 代码提供元数据。作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。Java 注解是从 Java5 开始添加到 Java 的。
Java的注解,可以说是一种标识,标识一个类或者一个字段,常常是和反射,AOP结合起来使用。中间件一般会定义注解,如果某些类或字段符合条件,就执行某些能力。
什么是元注解
说简单点,就是 定义其他注解的注解 。
比如Override这个注解,就不是一个元注解。而是通过元注解定义出来的。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
这里面的@Target,@Retention就是元注解。
元注解有四个:@Target(表示该注解可以用于什么地方)、@Retention(表示在什么级别保存该注解信息)、@Documented(将此注解包含在javadoc中)、@Inherited(允许子类继承父类中的注解)。
一般@Target是被用的最多的。
@Retention
指定被修饰的注解的生命周期,即注解在源代码、编译时还是运行时保留。它有三个可选的枚举值:SOURCE、CLASS和RUNTIME。默认为CLASS。
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface MyRuntimeAnnotation {
// some elements and values
}
@Target
指定被修饰的注解可以应用于的元素类型,如类、方法、字段等。这样可以限制注解的使用范围,避免错误使用。
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface MyTargetAnnotation {
// some elements and values
}
@Documented
用于指示注解是否会出现在生成的Java文档中。如果一个注解被@Documented元注解修饰,则该注解的信息会出现在API文档中,方便开发者查阅。
import java.lang.annotation.Documented;
@Documented
public @interface MyDocumentedAnnotation {
// some elements and values
}
@Inherited
指示被该注解修饰的注解是否可以被继承。默认情况下,注解不会被继承,即子类不会继承父类的注解。但如果将一个注解用@Inherited修饰,那么它就可以被子类继承。
有了equals为啥需要hashCode方法
在Java中,equals()和hashCode()方法通常是成对的,它们在使用基于Hash机制的数据结构时非常重要,例如HashMap、HashSet和Hashtable等。
- equals():用于判断两个对象是否相等
- hashCode:生成对象的哈希码,返回值是一个整数,用于确定对象在哈希表中的位置。
为什么需要hashCode,主要是为了方便用在Hash结构的数据结构中,因为对于这种数据结构来说,想要把一个对象存进去,需要定位到他应该存放在哪个桶中,而这个桶的位置,就需要通过一个整数来获取,然后再对桶的长度取模(实际hashmap要比这复杂一些)
那么,怎么能快速获取一个和这个对象有关的整数呢,那就是hashCode方法了。所以,hashCode的结果是和对象的内容息息相关的。那么也就意味着如果两个对象通过equals()方法比较是相等的,那么它们的hashCode()方法必须返回相同的整数值。
那么,在一个对象中,定义了equals方法之后,同时还需要定义hashCode方法, 因为这样在向hashMap、hashTable等中存放的时候,才能快速的定位到位置。
所以,基于两方面考虑,一方面是效率,hashCode() 方法提供了一种快速计算对象哈希值的方式,这些哈希值用于确定对象在哈希表中的位置。这意味着可以快速定位到对象应该存储在哪个位置或者从哪个位置检索,显著提高了查找效率。
另外一方面是可以和equals做协同来保证数据的一致性和准确性。根据 Java 的规范,如果两个对象通过 equals() 方法比较时是相等的,那么这两个对象的 hashCode() 方法必须返回相同的整数值。如果违反了这一规则,将导致哈希表等数据结构无法正确地处理对象,从而导致数据丢失和检索失败。
final、finally、finalize有什么区别
final、finally、finalize有什么区别?这个问题就像周杰、周杰伦和周星驰之间有啥关系的问题一样。其实没啥关系,放在一起比较无非是名字有点像罢了。
final、finally和finalize是Java中的三个不同的概念。
- final:用于声明变量、方法或类,使之不可变、不可重写或不可继承。
- finally:是异常处理的一部分,用于确保代码块(通常用于资源清理)总是执行。
- finalize:是Object类的一个方法,用于在对象被垃圾回收前执行清理操作,但通常不推荐使用。
final
final是一个关键字,可以用来修饰变量、方法和类。分别代表着不同的含义。
final变量:即我们所说的常量,一旦被赋值后,就不能被修改。
final int x = 100;
// x = 200; // 编译错误,不能修改final变量的值
public static final String AUTHOR_NAME = "Aaron";
final方法:不能被子类重写。
public final void show() {
// ...
}
final类:不能被继承。
public final class MyFinalClass {
// ...
}
finally
finally是一个用于异常处理,它和try、catch块一起使用。无论是否捕获或处理异常,finally块中的代码总是执行(程序正常执行的情况)。通常用于关闭资源,如输入/输出流、数据库连接等。
try {
// 可能产生异常的代码
} catch (Exception e) {
// 异常处理代码
} finally {
// 清理代码,总是执行
}
finalize
finalize是Object类的一个方法,用于垃圾收集过程中的资源回收。在对象被垃圾收集器回收之前,finalize方法会被调用,用于执行清理操作(例如释放资源)。但是,不推荐依赖finalize方法进行资源清理,因为它的调用时机不确定且不可靠。
protected void finalize() throws Throwable {
// 在对象被回收时执行清理工作
}