《掌握 Java:从基础到高级概念的综合指南》(6/15)

news2024/11/28 22:38:44

目录

1. 引言

2. 泛型概述

2.1 泛型的定义与使用

2.2 泛型方法

2.3 泛型通配符

3. 注解概述

3.1 内置注解

3.2 自定义注解

3.3 注解处理器 (APT)

4. 泛型与注解对比总结

5. 结论


Java 中的泛型与注解 (Annotation)

1. 引言

Java 泛型和注解是 Java 语言中两个重要的特性,它们极大地提高了代码的可读性、类型安全性以及灵活性。泛型 (Generics) 允许编写与特定数据类型无关的代码,从而提高代码的重用性和类型安全性。注解 (Annotations) 则用于在代码中添加元数据,帮助编译器、开发工具或运行时做出特定的处理。本篇文章将深入探讨 Java 中泛型与注解的概念、使用方式及其应用场景,结合代码示例进行详细说明。

2. 泛型概述

泛型是 Java SE 5 引入的特性,允许类、接口和方法操作指定的类型,减少了类型转换的麻烦并提供编译期的类型检查。

2.1 泛型的定义与使用

泛型允许在定义类或方法时使用类型参数,这样可以在使用时指定具体的类型。

代码示例:泛型类的定义与使用

// 定义一个泛型类
public class Box<T> {
    private T content;

    public void setContent(T content) {
        this.content = content;
    }

    public T getContent() {
        return content;
    }

    public static void main(String[] args) {
        Box<String> stringBox = new Box<>();
        stringBox.setContent("Hello Generics");
        System.out.println("Content: " + stringBox.getContent());

        Box<Integer> integerBox = new Box<>();
        integerBox.setContent(123);
        System.out.println("Content: " + integerBox.getContent());
    }
}
  • 代码解析:

    • Box<T> 是一个泛型类,其中 T 是类型参数,可以在实例化时指定具体的类型。

    • 通过 Box<String>Box<Integer> 创建不同类型的对象,避免了类型转换的风险。

2.2 泛型方法

泛型方法是在方法定义中引入类型参数,通常用于工具类或需要通用性的场景。

代码示例:泛型方法的定义与使用

public class GenericMethodExample {
    // 定义一个泛型方法
    public static <T> void printArray(T[] array) {
        for (T element : array) {
            System.out.print(element + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        Integer[] intArray = {1, 2, 3, 4, 5};
        String[] strArray = {"A", "B", "C", "D"};

        printArray(intArray);  // 输出: 1 2 3 4 5
        printArray(strArray);  // 输出: A B C D
    }
}
  • 代码解析:

    • <T> 在方法名之前声明了类型参数 T,使得该方法可以处理不同类型的数组。

    • 泛型方法使代码更加灵活,适用于多种类型的数据。

2.3 泛型通配符

泛型通配符 (?) 用于表示未知的类型边界,通常用于方法的参数中以增加灵活性。

  • 无界通配符<?>,可以表示任意类型。

  • 有界通配符<? extends T>,表示类型是 TT 的子类;<? super T>,表示类型是 TT 的父类。

代码示例:泛型通配符的使用

import java.util.List;

public class WildcardExample {
    // 使用无界通配符
    public static void printList(List<?> list) {
        for (Object element : list) {
            System.out.print(element + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        List<Integer> intList = List.of(1, 2, 3);
        List<String> strList = List.of("A", "B", "C");

        printList(intList);  // 输出: 1 2 3
        printList(strList);  // 输出: A B C
    }
}
  • 代码解析:

    • 使用 <?> 表示可以接受任意类型的 List,使得方法 printList 具有更大的通用性。

3. 注解概述

注解是 Java 中用于在代码中嵌入元数据的特殊语法,它们不会影响程序的逻辑运行,但可以在编译阶段或运行时起作用。Java SE 5 引入了注解,并且提供了一些内置的注解,如 @Override@Deprecated@SuppressWarnings

3.1 内置注解
  • @Override:用于标识方法覆盖了父类的方法。

  • @Deprecated:用于标识某个类或方法已过时,不建议使用。

  • @SuppressWarnings:用于抑制编译器产生的特定警告。

代码示例:内置注解的使用

public class AnnotationExample {
    @Deprecated
    public void oldMethod() {
        System.out.println("This method is deprecated.");
    }

    @Override
    public String toString() {
        return "AnnotationExample instance";
    }

    @SuppressWarnings("unchecked")
    public void useUncheckedOperation() {
        List rawList = List.of("A", "B");  // 使用原始类型
        System.out.println("Raw list: " + rawList);
    }

    public static void main(String[] args) {
        AnnotationExample example = new AnnotationExample();
        example.oldMethod();
        System.out.println(example);
        example.useUncheckedOperation();
    }
}
  • 代码解析:

    • @Deprecated 表明 oldMethod 方法已过时,尽量避免使用。

    • @Override 用于确保 toString() 方法正确覆盖了父类的方法。

    • @SuppressWarnings 用于抑制使用原始类型时产生的编译警告。

3.2 自定义注解

Java 允许开发者定义自己的注解,以在代码中添加更多特定的信息。

代码示例:自定义注解

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

// 定义自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface MyAnnotation {
    String value();
}

@MyAnnotation(value = "Class Annotation")
public class CustomAnnotationExample {
    @MyAnnotation(value = "Method Annotation")
    public void myMethod() {
        System.out.println("This is a method with custom annotation.");
    }

    public static void main(String[] args) {
        CustomAnnotationExample example = new CustomAnnotationExample();
        example.myMethod();
    }
}
  • 代码解析:

    • @Retention 指定注解的保留策略,RUNTIME 表示注解会在运行时保留,可以通过反射访问。

    • @Target 指定注解可以应用的程序元素,如类、方法等。

    • 自定义注解 @MyAnnotation 被用于类和方法上,起到标记的作用。

3.3 注解处理器 (APT)

注解处理器用于在编译时处理注解,可以自动生成代码或进行特定的编译检查。Java 提供了 Annotation Processing Tool (APT) 来实现这一功能,通常结合 @SupportedAnnotationTypes@SupportedSourceVersion 等注解使用。

代码示例:注解处理器

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import java.util.Set;

@SupportedAnnotationTypes("MyAnnotation")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class MyAnnotationProcessor extends AbstractProcessor {
    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        for (Element element : roundEnv.getElementsAnnotatedWith(MyAnnotation.class)) {
            System.out.println("Found element with MyAnnotation: " + element);
        }
        return true;
    }
}
  • 代码解析:

    • 注解处理器继承自 AbstractProcessor,并通过 @SupportedAnnotationTypes 指定它要处理的注解类型。

    • 在编译期间,处理器会找到所有使用 @MyAnnotation 的元素,并对其进行处理。

4. 泛型与注解对比总结

特性泛型 (Generics)注解 (Annotations)
目的提供类型安全、代码复用性添加元数据,帮助编译器和工具处理
主要应用场景集合类、工具类、通用性代码标记类、方法、字段以进行特定操作
引入版本Java SE 5Java SE 5
类型参数T, E, K, V, etc.元数据,通过 @interface 定义

5. 结论

泛型与注解是 Java 语言中的两个关键特性,泛型提供了类型安全的代码编写方式,使得开发者可以编写通用的、复用性高的代码,而注解则通过添加元数据来增强代码的可读性、降低错误率,并提高自动化处理的能力。本篇文章详细介绍了泛型的定义与使用、泛型方法、通配符以及注解的内置和自定义用法。掌握这些概念,可以让开发者编写出更加灵活、高效和易于维护的 Java 程序。在后续的文章中,我们将深入探讨 Java 中的多线程与并发编程,以帮助您更好地理解 Java 的高级特性。

希望本篇文章能够帮助你理解 Java 中的泛型与注解的使用场景和实现方式。如果有任何疑问或想深入了解某些概念,欢迎在评论区留言!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2227415.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构初阶———顺序表

一、引言 首先我们应该回顾动态内存开辟的原理 这部分知识对于内存访问至关重要 然而顺序表的实现都是基于C语言的基础 包括指针 结构体 动态内存开辟 realloc malloc h函数的使用与实现 既然要学习顺序表 我们不仅要知道这个实现是基于C语言知识的基础 我们还要知道什么…

疯狂Spring Boot讲义[推荐1]

《疯狂Spring Boot讲义》是2021年电子工业出版社出版的图书&#xff0c;作者是李刚 《疯狂Spring Boot终极讲义》不是一本介绍类似于PathVariable、MatrixVariable、RequestBody、ResponseBody这些基础注解的图书&#xff0c;它是真正讲解Spring Boot的图书。Spring Boot的核心…

DBC文件当中新建CANFD等类型的报文

同学最近有添加CANFD报文的需求&#xff0c;需要用到CANFD类型报文的DBC文件&#xff0c;这下就难住我了&#xff0c;我之前用的DBC文件只有“CAN Standard”“CAN Extended”两种类型&#xff0c;压根没见过FD的。 后来他找到了项目之前的DBC&#xff0c;打开来看&#xff0c…

RabbitMQ集群搭建及使用

1. 概述 前提条件&#xff1a;linux服务器下已经安装好了docker服务。 本文档将搭建一个三台RabbitMQ的集群&#xff0c;包括三个RabbitMQ容器安装在同一服务器和三台不同的服务器。 2. 集群搭建 在一台服务器上创建三个RabbitMQ容器。 2.1.1. 创建容器 执行以下命令创建三…

卡方检验方法概述与类型——四格表和R*C表卡方检验案例

卡方检验是以卡方分布为基础&#xff0c;针对定类数据资料的常用假设检验方法。其理论思想是判断实际观测到的频数与有关总体的理论频数是否一致。 卡方统计量是实际频数与理论频数吻合程度的指标。卡方值越小&#xff0c;表明实际观察频数与理论频数越接近&#xff0c;反之卡…

three.js使用ShaderMaterial实现聚光灯光源demo

文章目录 顶点片元全部 核心&#xff1a; 顶点 varying vec3 vNormal;varying vec3 vViewPosition;void main() {vNormal normalMatrix * normal;vNormal normalize( vNormal );vec4 modelViewPosition modelViewMatrix * vec4(position, 1.0);gl_Position projectionMat…

WPF+MVVM案例实战(三)- 动态数字卡片效果实现

1、创建项目 打开 VS2022 &#xff0c;新建项目 Wpf_Examples&#xff0c;创建各层级文件夹&#xff0c;安装 CommunityToolkit.Mvvm 和 Microsoft.Extensions.DependencyInjectio NuGet包,完成MVVM框架搭建。搭建完成后项目层次如下图所示&#xff1a; 这里如何实现 MVVM 框…

深入理解 SQL 中的 WITH AS 语法

在日常数据库操作中&#xff0c;SQL 语句的复杂性往往会影响到查询的可读性和维护性。为了解决这个问题&#xff0c;Oracle 提供了 WITH AS 语法&#xff0c;这一功能可以极大地简化复杂查询&#xff0c;提升代码的清晰度。本文将详细介绍 WITH AS 的基本用法、优势以及一些实际…

【云原生】Kubernets1.29部署StorageClass-NFS作为存储类,动态创建pvc(已存在NFS服务端)

文章目录 在写redis集群搭建的时候,有提到过使用nfs做storageclass,那时候kubernetes是1.20版本,https://dongweizhen.blog.csdn.net/article/details/130651727 现在使用的是kubernetes 1.29版本,根据之前的修改方式并未生效,反而提示:Error: invalid argument "Re…

算法日记 11 day 二叉树

新的篇章&#xff0c;二叉树&#xff01;&#xff01;&#xff01; 二叉树的种类 满二叉树&#xff1a;如果一棵二叉树只有度为0的结点和度为2的结点&#xff0c;并且度为0的结点在同一层上&#xff0c;则这棵二叉树为满二叉树。 这棵二叉树为满二叉树&#xff0c;也可以说深度…

IDEA->EasyCode(mapper.xml) 字段无逗号分隔和修改全局变量问题

1.mapperxml字段无逗号分隔 在easycode的设置里找到&#xff1a; 1、Template下的 mapper.xml.vm脚本 2、Global Config下的 mybatisSupport.vm脚本 将脚本里的 $velocityHasNext 替换成 $foreach.hasNext&#xff0c;然后保存。Mybatis-Plus框架操作一样 github->issue连…

红队工具---Behinder学习

1.什么是Behinder&#xff1f; Behinder 是一款用于网络渗透测试的安全工具&#xff0c;主要用于对 Web 应用进行攻击和漏洞利用。它提供了强大的功能&#xff0c;是一款红队的大杀器&#xff0c;几乎是现代web安全必须学习的一款webshell管理工具。 主要用途 渗透测试&#…

中航资本:商业卫星产业链建设加快 无人机军民两用空间广阔

互联网医疗迎多重边沿改进 我国居民医疗保健开支稳步添加&#xff0c;据国家统计局数据&#xff0c;2023年全国居民医疗保健人均消费开支为2460元&#xff0c;占人均消费总开支的比例从2018年的8.5%前进至2023年的9.2%。跟着慢病患者群扩展、业态相似的外卖、产品电商翻开以及…

基于springboot+vue实现的免费体育馆场地预约系统 (源码+L文+ppt)4-099

基于springbootvue实现的免费体育馆场地预约系统 &#xff08;源码L文ppt&#xff09;4-099 4.1 系统总体结构设计 本系统是基于B/S架构的网站系统&#xff0c;分为系统前台和系统后台&#xff0c;前台主要是提供给注册用户和未注册登录的游客使用的&#xff0c;包括首页、场馆…

雷军救WPS“三次”,WPS注入新生力量,不再“抄袭”微软

救WPS“三次” 1989年&#xff0c;求伯君用128万行代码编写出了WPS1.0&#xff0c;宣告了中国自主办公时代的开启。 那时候&#xff0c;雷军还在武汉大学深造&#xff0c;他早就把求伯君当成了自己的榜样&#xff0c;这一来二去的&#xff0c;雷军和WPS之间也就结下了不解之缘…

基于GFlowNets的蚁群抽样算法在组合优化中的应用(arXiv 2024)(未完) -1

文章目录 Abstract1 Introduction2 Related works2.1 蚁群优化2.2 神经组合优化2.3 GFlowNets与组合优化3 Preliminary3.1 旅行商问题3.2 蚁群优化3.3 生成流网络Abstract 本文介绍了一种神经引导的概率搜索算法——生成流蚁群采样器(GFACS),用于解决组合优化(CO)问题。G…

【C++】类和对象(四):析构函数

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家了解C的析构函数&#xff0c;如果你觉得我写的还不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 目录 1. 概念2. 特性 1. 概念 通过前面构造函数的学习&#xff0c;我们知道一个对象是怎么来的…

VulkanTutorial(8·Shader modules)

Shader modules 与早期的API不同&#xff0c;Vulkan中的着色器代码必须以字节码格式指定&#xff0c;而不是人类可读的语法&#xff0c;如GLSL和HLSL。这种字节码格式称为SPIR-V它是一种可用于编写图形和计算着色器的格式 使用像SPIR-V这样简单的字节码格式&#xff0c;不会面…

详解PHP正则表达式中的转义操作

PHP正则表达式中的特殊字符和转义 在 PHP 正则表达式中&#xff0c;有许多特殊字符具有特定的意义。这些特殊字符通常用于定义匹配模式的一部分&#xff0c;或者改变匹配的行为。以下是 PHP 正则表达式中一些常用的特殊字符及其含义: .匹配除换行符之外的任何单个字符 ^在方括…

27.Redis哨兵架构

Redis哨兵高可用架构 Sentinel&#xff08;哨兵&#xff09;是一种特殊的 Redis 服务&#xff0c;其主要功能并非提供常规的读写服务&#xff0c;而是专门用于监控 Redis 实例节点。 1.在哨兵架构下&#xff0c;客户端&#xff08;client 端&#xff09;首次会从哨兵处找出 Re…