Java基础教程(14)-Java中的枚举类,泛型和注解

简介: 【4月更文挑战第14天】枚举类型(enum)是固定常量集合,Java中用`enum`定义。特点包括:使用enum关键字,定义类型名和值,可独立或嵌入定义,可实现接口,定义变量和方法。枚举在switch语句中适用,每个枚举值在JVM中唯一,不能继承Enum类。

什么是枚举类

枚举类型(enum type)是指由一组固定的常量组成合法的类型。Java 中由关键字enum 来定义一个枚举类型

Java 定义枚举类型的语句有以下特点:
1) 使用关键字 enum ;
2) 类型名称,比如这里的 Season ;
3) 一串允许的值,
4) 枚举可以单独定义在一个文件中,也可以嵌在其它 Java 类中;
5) 枚举可以实现一个或多个接口(Interface);
6) 可以定义新的变量 ;
7) 可以定义新的方法;
8) 可以定义根据具体枚举值而相异的类

enum 就和 class 一样,只是一个关键字,他并不是一个类;
当我们使用 enmu 来定义一个枚举类型的时候,编译器会自动帮我们创建一个 final类型的类继承 Enum 类,所以枚举类型不能被继承

Java 枚举如何比较

java 枚举值比较用双等于号和 equals 方法没啥区别,两个随便用都是一样的效果。

因为 enum 类型的每个常量在JVM中只有一个唯一实例; 枚举 Enum 类的 equals 方法默认实现就是通过 == 来比较的;

枚举类可以应用在 switch 语句中。因为枚举类天生具有类型信息和有限个枚举常量,所以比 int 、 String 类型更适合用在 switch 语句中.

什么是泛型:

Java 泛型( generics) 是 JDK 5 中引⼊的⼀个新特性, 允许在定义类和接口的时候使⽤类型参数( type parameter) 。
声明的类型参数在使⽤时⽤具体的类型来替换

泛型最⼤的好处是可以提⾼代码的复⽤性。 以 List 接⼜为例,我们可以将 String、Integer 等类型放⼊List 中, 如不⽤泛型, 存放 String 类型要写⼀个 List 接口, 存放Integer 要写另外⼀个 List 接口, 泛型可以很好的解决这个问题;

泛型就是定义一种模板,例如 ArrayList ,然后在代码中为用到的类创建对应的 ArrayList<类型>;,既实现了编写一次,万能匹配,又通过编译器保证了类型安全;

  • 使用泛型时,把泛型参数 替换为需要的class类型
  • 不指定泛型参数类型时,编译器会给出警告,且只能将 视为 Object 类型
  • 可以在接口中定义泛型类型,实现此接口的类必须实现正确的泛型类型

  • 编写泛型时,需要定义泛型类型 ;

  • 静态方法不能引用泛型类型 ,必须定义其他类型(例如 )来实现静态泛型方法;
  • 泛型可以同时定义多种类型,例如 Map 。

类型擦除:

类型擦除指的是通过类型参数合并,将泛型类型实例关联到同一份字节码上。编译器只为泛型类型生成一份字节码,并将其实例关联到这份字节码上。

类型擦除的主要过程如下:

  1. 将所有的泛型参数用其最左边界(最顶级的父类型)类型替换
  2. 移除所有的类型参数。
  • 1、虚拟机中没有泛型,只有普通类和普通方法,所有泛型类的类型参数在编译时都会被擦除,泛型类并没有自己独有的 Class 类对象。比如并不存在 List.class 或是List.class,而只有 List.class。
  • 2、创建泛型对象时请指明类型,让编译器尽早的做参数检查;
  • 3、不要忽略编译器的警告信息,那意味着潜在的ClassCastException 等着你。
  • 4、 泛型的类型参数不能用在 Java 异常处理的 catch 语句中。因为异常处理是由JVM 在运行时刻来进行的。由于类型信息被擦除,JVM 是无法区分两个异常类型MyException和MyException的。对于 JVM 来说,它们都是MyException 类型的。也就无法执行与异常对应的 catch 语句。

通配符

通配符分为限定通配符和非限定通配符

  • 限定通配符对类型进⾏限制, 泛型中有两种限定通配符:

表示类型的上界,格式为:<? extends T>,即类型必须为 T 类型或者 T 子类
<? extends T> 允许调用读方法 T get() 获取 T 的引用,但不允许调用写方法 set(T) 传入 T 的引用(传入 null 除外)

表示类型的下界,格式为:<? super T>,即类型必须为 T 类型或者 T 的父类
<? super T> 允许调用写方法 set(T) 传入 T 的引用,但不允许调用读方法 Tget() 获取 T 的引用(获取 Object 除外)。

  • 泛型类型必须⽤限定内的类型来进⾏初始化,否则会导致编译错误。
  • ⾮限定通配符表⽰可以⽤任意泛型类型来替代,类型为

泛型中 K T V E ?的含义

E - Element (在集合中使用,因为集合中存放的是元素)
T - Type(Java 类)
K - Key(键)
V - Value(值)
N - Number(数值类型)
? - 表示不确定的 java 类型(无限制通配符类型)
S、U、V - 2nd、3rd、4th types

List和原始类型 List 之间的区别

原始类型 List 和带参数类型 List之间的主要区别是,在编译时编译器不会对原始类型进行类型安全检查,却会对带参数的类型进行检查。通过使用 Object 作为类型,可以告知编译器该方法可以接受任何类型的对象,比如String 或 Integer。

它们之间的第二点区别是,你可以把任何带参数的类型传递给原始类型 List,但却不能把 List传递给接受 List的方法,因为会产生编译错误

List<?>和 List之间的区别是什么?
List<?> 是一个未知类型的 List,而 List<Object> 其实是任意类型的 List。你可以把List<String>, List<Integer>赋值给 List<?>,却不能把 List<String>赋值给 List<Object>
AI 代码解读

什么是注解(Annotation)?

注解是放在Java源码的类、方法、字段、参数前的一种特殊“注释”:注解可以被编译器打包进入class文件,因此,注解是一种用作标注的“元数据”。

Java的注解可以分为三类:

  • 第一类是由编译器使用的注解,例如:

    @Override :让编译器检查该方法是否正确地实现了覆写;
    @SuppressWarnings :告诉编译器忽略此处代码产生的警告。
    这类注解不会被编译进入 .class 文件,它们在编译后就被编译器扔掉了。

  • 第二类是由工具处理 .class 文件使用的注解,比如有些工具会在加载class的时候,对class做动态修改,实现一些特殊的功能。这类注解会被编译进入 .class 文件,但加载结束后并不会存在于内存中。这类注解只被一些底层库使用,一般我们不必自己处理。

  • 第三类是在程序运行期能够读取的注解,它们在加载后一直存在于JVM中,这也是最常用的注解。

定义一个注解时,还可以定义配置参数。配置参数可以包括:

所有基本类型;
String;
枚举类型;
基本类型、String以及枚举的数组。

因为配置参数必须是常量,所以,上述限制保证了注解在定义时就已经确定了每个参数的值。

自定义注解

Java语言使用 @interface 语法来定义注解( Annotation )

package com.demo;

//定义一个注解
public @interface Report {
    int type() default 0;  //无参方法 有默认值
    String level() default "0";
    String value() default "";
}
AI 代码解读

注解的参数类似无参数方法,可以用 default 设定一个默认值(强烈推荐)。最常用的参数应当命名为 value 。

有一些注解可以修饰其他注解,这些注解就称为元注解(meta annotation)。Java标准库已经定义了一些元注解,我们只需要使用元注解,通常不需要自己去编写元注解。

package com.demo;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 最常用的元注解是 @Target 。使用 @Target 可以定义 Annotation 能够被应用于源码的哪些位
 * 置:
 * 类或接口: ElementType.TYPE ;
 * 字段: ElementType.FIELD ;
 * 方法: ElementType.METHOD ;
 * 构造方法: ElementType.CONSTRUCTOR ;
 * 方法参数: ElementType.PARAMETER 。
 * 
 * 另一个重要的元注解 @Retention 定义了 Annotation 的生命周期:
 * 仅编译期: RetentionPolicy.SOURCE ;
 * 仅class文件: RetentionPolicy.CLASS ;
 * 运行期: RetentionPolicy.RUNTIME 。
 * 如果 @Retention 不存在,则该 Annotation 默认为 CLASS 。因为通常我们自定义
 * 的 Annotation 都是 RUNTIME ,所以,务必要加
 * 上 @Retention(RetentionPolicy.RUNTIME) 这个元注解
 * */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Report {
    int type() default 0;  //无参方法 有默认值
    String level() default "0";
    String value() default "";
}
AI 代码解读

@Target 定义的 value 是 ElementType[] 数组,只有一个元素时,可以省略数组的写法。

定义 Annotation 的步骤:

  • 第一步,用 @interface 定义注解
  • 第二步,添加参数、默认值:
  • 第三步,用元注解配置注解:

读取自定义注解

注解定义后也是一种 class ,所有的注解都继承自java.lang.annotation.Annotation ,因此,读取注解,需要使用反射API;

Java提供的使用反射API读取 Annotation 的方法包括:

判断某个注解是否存在于 Class 、 Field 、 Method 或 Constructor :

Class.isAnnotationPresent(Class)
Field.isAnnotationPresent(Class)
Method.isAnnotationPresent(Class)
Constructor.isAnnotationPresent(Class)

使用反射API读取Annotation:

Class.getAnnotation(Class)
Field.getAnnotation(Class)
Method.getAnnotation(Class)
Constructor.getAnnotation(Class)

目录
打赏
0
0
0
0
1634
分享
相关文章
重学Java基础篇—Java类加载顺序深度解析
本文全面解析Java类的生命周期与加载顺序,涵盖从加载到卸载的七个阶段,并深入探讨初始化阶段的执行规则。通过单类、继承体系的实例分析,明确静态与实例初始化的顺序。同时,列举六种触发初始化的场景及特殊场景处理(如接口初始化)。提供类加载完整流程图与记忆口诀,助于理解复杂初始化逻辑。此外,针对空指针异常等问题提出排查方案,并给出最佳实践建议,帮助开发者优化程序设计、定位BUG及理解框架机制。最后扩展讲解类加载器层次与双亲委派机制,为深入研究奠定基础。
144 0
【Java基础-环境搭建-创建项目】IntelliJ IDEA创建Java项目的详细步骤
IntelliJ IDEA创建Java项目的图文详细步骤,手把手带你创建Java项目
236 10
【Java基础-环境搭建-创建项目】IntelliJ IDEA创建Java项目的详细步骤
java 编程基础入门级超级完整版教程详解
这份文档是针对Java编程入门学习者的超级完整版教程,涵盖了从环境搭建到实际项目应用的全方位内容。首先介绍了Java的基本概念与开发环境配置方法,随后深入讲解了基础语法、控制流程、面向对象编程的核心思想,并配以具体代码示例。接着探讨了常用类库与API的应用,如字符串操作、集合框架及文件处理等。最后通过一个学生成绩管理系统的实例,帮助读者将理论知识应用于实践。此外,还提供了进阶学习建议,引导学员逐步掌握更复杂的Java技术。适合初学者系统性学习Java编程。资源地址:[点击访问](https://pan.quark.cn/s/14fcf913bae6)。
136 2
接替此文【下篇-服务端+后台管理】优雅草蜻蜓z系统JAVA版暗影版为例-【蜻蜓z系列通用】-2025年全新项目整合搭建方式-这是独立吃透代码以后首次改变-独立PC版本vue版搭建教程-优雅草卓伊凡
接替此文【下篇-服务端+后台管理】优雅草蜻蜓z系统JAVA版暗影版为例-【蜻蜓z系列通用】-2025年全新项目整合搭建方式-这是独立吃透代码以后首次改变-独立PC版本vue版搭建教程-优雅草卓伊凡
291 96
接替此文【下篇-服务端+后台管理】优雅草蜻蜓z系统JAVA版暗影版为例-【蜻蜓z系列通用】-2025年全新项目整合搭建方式-这是独立吃透代码以后首次改变-独立PC版本vue版搭建教程-优雅草卓伊凡
Java注解的底层源码剖析与技术认识
Java注解(Annotation)是Java 5引入的一种新特性,它提供了一种在代码中添加元数据(Metadata)的方式。注解本身并不是代码的一部分,它们不会直接影响代码的执行,但可以在编译、类加载和运行时被读取和处理。注解为开发者提供了一种以非侵入性的方式为代码提供额外信息的手段,这些信息可以用于生成文档、编译时检查、运行时处理等。
161 7
注解的艺术:Java编程的高级定制
注解是Java编程中的高级特性,通过内置注解、自定义注解及注解处理器,可以实现代码的高度定制和扩展。通过理解和掌握注解的使用方法,开发者可以提高代码的可读性、可维护性和开发效率。在实际应用中,注解广泛用于框架开发、代码生成和配置管理等方面,展示了其强大的功能和灵活性。
118 25
重学Java基础篇—Java对象创建的7种核心方式详解
本文全面解析了Java中对象的创建方式,涵盖基础到高级技术。包括`new关键字`直接实例化、反射机制动态创建、克隆与反序列化复用对象,以及工厂方法和建造者模式等设计模式的应用。同时探讨了Spring IOC容器等框架级创建方式,并对比各类方法的适用场景与优缺点。此外,还深入分析了动态代理、Unsafe类等扩展知识及注意事项。最后总结最佳实践,建议根据业务需求选择合适方式,在灵活性与性能间取得平衡。
198 3
|
4月前
|
重学Java基础篇—Java泛型深度使用指南
本内容系统介绍了Java泛型的核心价值、用法及高级技巧。首先阐述了泛型在**类型安全**与**代码复用**中的平衡作用,解决强制类型转换错误等问题。接着详细讲解了泛型类定义、方法实现、类型参数约束(如边界限定和多重边界)、通配符应用(PECS原则)以及类型擦除的应对策略。此外,还展示了泛型在通用DAO接口、事件总线等实际场景的应用,并总结了命名规范、边界控制等最佳实践。最后探讨了扩展知识,如通过反射获取泛型参数类型。合理运用泛型可大幅提升代码健壮性和可维护性,建议结合IDE工具和单元测试优化使用。
80 1
|
4月前
|
重学Java基础篇—Java Object类常用方法深度解析
Java中,Object类作为所有类的超类,提供了多个核心方法以支持对象的基本行为。其中,`toString()`用于对象的字符串表示,重写时应包含关键信息;`equals()`与`hashCode()`需成对重写,确保对象等价判断的一致性;`getClass()`用于运行时类型识别;`clone()`实现对象复制,需区分浅拷贝与深拷贝;`wait()/notify()`支持线程协作。此外,`finalize()`已过时,建议使用更安全的资源管理方式。合理运用这些方法,并遵循最佳实践,可提升代码质量与健壮性。
120 1
自研Java框架 Sunrays-Framework使用教程「博客之星」
### Sunrays-Framework:助力高效开发的Java微服务框架 **Sunrays-Framework** 是一款基于 Spring Boot 构建的高效微服务开发框架,深度融合了 Spring Cloud 生态中的核心技术组件。它旨在简化数据访问、缓存管理、消息队列、文件存储等常见开发任务,帮助开发者快速构建高质量的企业级应用。 #### 核心功能 - **MyBatis-Plus**:简化数据访问层开发,提供强大的 CRUD 操作和分页功能。 - **Redis**:实现高性能缓存和分布式锁,提升系统响应速度。 - **RabbitMQ**:可靠的消息队列支持,适用于异步
自研Java框架 Sunrays-Framework使用教程「博客之星」

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问