广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java泛型与注解全面分析讲解
  • 224
分享到

Java泛型与注解全面分析讲解

2024-04-02 19:04:59 224人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录1.什么是泛型2.为何使用泛型2.1.如何定义泛型2.2.通配符2.3.受限泛型2.4.泛型接口2.5.泛型方法3.java高级--注解3.1.预定义注解3.2.自定义注解(初级

1.什么是泛型

其实我们在使用集合时就用过泛型List<T> 创建一个List对象List<Student> list=new ArrayList();<T>它就是泛型。

所谓的泛型就是在类定义时,不为类中属性和方法指定数据类型,而是在类对象创建时为其指定相应的数据类型。

2.为何使用泛型

例子: 要求定义一个Point点类,该类中属性有x坐标和y坐标。

要求: x和y的值可以都是整数类型。

​ x和y的值可以都是小数类型。

​ x和y的值可以都是字符串类型。

如何定义该类呢? 如何确定属性的类型。----可以想到使用Object类型

如果我们为坐标一个赋值整数,一个赋值为字符串,这时不会报错 ,

但是它违背了我们设计的要求,这就是我们提到的数据类型安全问题。如何解决数据类型安全问题?可以使用泛型来解决,使用泛型就保证了数据类型安全问题 。

2.1.如何定义泛型

泛型可以定义在类上,接口上,方法上。 泛型类,泛型接口以及泛型方法。

泛型可以解决数据类型的安全性问题,其主要原理是在类声明时通过一个标识表示类中某个属性的数据类型或者是某个方法的返回值及参数类型。这样在类声明或者实例化时只要指定好需要的类型即可。

格式:

public class 类名<泛型标志,泛型标志....>{

//类成员

}

代码展示:

//T标志可以任意起名-----若此处有多个标志时,使用时必须为每个泛型指定数据类型
public class Student<T> {
    private T name;
    private T age;
    public void show(){
        System.out.println("name:"+name+"age:"+age);
    }
    public Student() {
    }
    public Student(T name, T age) {
        this.name = name;
        this.age = age;
    }
    public T getName() {
        return name;
    }
    public void setName(T name) {
        this.name = name;
    }
    public T getAge() {
        return age;
    }
    public void setAge(T age) {
        this.age = age;
    }
}

测试类:

public class StudentTest {
    public static void main(String[] args) {
        Student<Integer> stu=new Student<Integer>(33,44);
        stu.show();
        //若指定泛型类型默认为Object
        Student<String> stu1=new Student<>("张三","22");
        stu1.show();
        Student stu2=new Student("李四","55");
        String age = (String) stu2.getAge();//若想使用真正的类型接受,那么必须进行强转
        System.out.println(age);
    }
}

2.2.通配符

开发中对象的引用传递是最常见的,但是如果在泛型类的操作中,在进行引用传递时泛型类型必须匹配才可以传递,否则是无法传递的。如果想传递,可以定义泛型为?通配符。

代码展示:

public class Test04 {
    public static void main(String[] args) {
            Info<Integer> i=new Info<>();
            i.setVar(25);
            fun(i);
            Info<String> i2=new Info<>();
            i2.setVar("张三");
            fun(i2); //如果下面不是使用通配符?则会报错  原因是如果为泛型类型:不但要求数据类型相同之外还要求泛型类型也匹配。
           Info<Double> i3=new Info<>();
           i3.setVar(25.5);
           fun(i3);
            //能不能设置泛型类型可以接受任意的类型呢? 我们可以使用同配置?
    }
    public static void fun(Info<?> info){
         info.show();
    }
}
//T标志可以任意起名.----> 那么在创建对象时,必须为每个泛型指定数据类型。
class Info<T>{
    private T var;
    public void show(){
        System.out.println("var========"+var);
    }
    public T getVar() {
        return var;
    }
    public void setVar(T var) {
        this.var = var;
    }
}

2.3.受限泛型

在引用传递中,在泛型操作中也可以设置一个泛型对象的范围上限和范围下限。范围上限使用extends关键字声明,表示参数化的类型可能是所指定的类型或者是此类型的子类,而范围下限使用super进行声明,表示参数化的类型可能是所指定的类型或者此类型的父类型。

语法:

[设置上限]

声明对象: 类名称<? extends 类> 对象名称;

定义类: [访问权限] 类名称<泛型标识 extends 类>{}

[设置下限]

声明对象: 类名称<? super 类> 对象名称;

定义类: [访问权限] 类名称<泛型标识 super 类>{}

代码展示:

public class ShangXiaXianTest {
    public static void main(String[] args) {
        Info<Number> i=new Info<>();
         fun2(i);
         Info<Object> i3=new Info<>();
         fun2(i3);
         Info<Integer> i4=new Info<>();
         fun2(i4);
    }
    //传递的参数泛型类型必须为Number的父类或者Number类型  下限
    public static void fun2(Info<? super Number> info){
        info.show();
    }
    //传递的参数泛型类型必须为Number的子类(注意String不是Number的子类)或者Number类型   上限
    public static void fun3(Info<? extends Number> info){
        info.show();
    }
    public static void fun(Info<?> info){
        info.show();
    }
}
class Info<T>{
    private T var;
    public void show(){
        System.out.println("var==============="+var);
    }
    public Info(T var) {
        this.var = var;
    }
    public Info() {
    }
    public T getVar() {
        return var;
    }
    public void setVar(T var) {
        this.var = var;
    }
}

2.4.泛型接口

上面那些例子都是使用泛型类。而在jdk1.5以后,泛型也可以定义在接口上了,定义接口的泛型和定义泛型类语法相似。

语法:

public interface 接口名<泛型标志,泛型标志....>{

//静态常量

//抽象方法

}

类如何实现泛型接口 代码展示:

public class JieKouTest {
    public static void main(String[] args) {
        Upan u=new Upan();
        u.name="小可爱";
        Mouse<String> mouse=new Mouse<>();
        mouse.t="5555";
        System.out.println(mouse.fun());
        System.out.println(u.fun());
    }
}
interface USB<T>{
    public static final String NAME="";//常量的命名必须全部大写
    public T fun();
    //JDK1.8后新特性
    default void fun2(){
    }
    static void fun3(){
    }
}
//子类也实现泛型和父类名相同的泛型
class Mouse<T> implements USB<T>{
    T t;
    @Override
    public T fun() {
        return t;
    }
}
//子类在实现接口时,确定泛型类型
class Upan implements USB<String>{
    public String name;
    @Override
    public String fun() {
        return name;
    }
}

2.5.泛型方法

前面学习的所有泛型操作都是将整个类进行泛型化,但同样也可以在类中定义泛型化的方法。泛型方法的定义与其所在的类是否是泛型类是没有任何关系的,所在的类可以是泛型类,也可以不是泛型类。

【泛型方法的简单定义】

[访问权限] <泛型标识> 泛型标识 方法名称(泛型标识 参数名称)

代码展示:

public class factorTest {
        String hello = Student.fun("hello");
        Integer fun = Student.fun(25);
        Double fun1 = Student.fun(25.0);
         System.out.println(hello+"--"+fun+"--"+fun1);
}
class Student{
    //泛型方法: static静态成员,随着类的加载而被加载到JVM内存中 常量池
    public static <T> T fun(T t){
        return t;
    }
    //泛型方法: static静态成员,随着类的加载而被加载到JVM内存中 常量池
    public static <T> Info<?> fun1(Info<? extends T> t){
        return t;
    }
}
class Info<T>{
}

3.java高级--注解

注释: java不会编译注释的内容,注释给程序员看的。

注解: 它是程序看,当程序看到这个注解时,就应该解析它。

譬如: @Controller @Override

注解的分类:

1. 预定义注解

2. 自定义注解

3. 元注解

3.1.预定义注解

预定义注解就是JDK自带的一些注解,该注解被JVM而解析。

1. @Override: 重写得注解。符合重写得规则。

2. @Deprecated: 表示已过时。

3. @SuppressWarnings: 表示压制警告。

4. @FunctionInterface: 表示函数式接口。表示该接口中有且仅有一个抽象方法。

3.2.自定义注解(初级)

语法:

public可以省略

public @interface 注解名{

//注解属性

}

代码展示:

public class Test {
    public static void main(String[] args) {
        Info i=new Info();
        i.name="张三";
        i.show();
    }
}
//定义好注解了
@interface My{
   //注解属性
}
//使用注解
@My
class Info{
    @My
    public String name;
    @My
    public void show(){
        System.out.println("show================="+name);
    }
}

注意: 使用注解和不使用注解没有区别

注解本身没有任何意义,它只有被解析了,才会赋予真正的意义。

我们后会使用反射来对象注解进行解析。

像:@Override 它被JVM解析,从而使其具有相应的意义。

​ @Controller @RequestMapping 它被spring框架解析,所以具有相应的意义。

3.3.元注解

定义在注解上的注解称为元注解。

@Controller它只能加在类上 @Override它只能加在方法上。

原因它使用了元注解可以设置注解使用的位置

1. @Target(value=可以取下面这些内容): 作用限制注解使用得位置。

TYPE,

FIELD,

METHOD,

PARAMETER,

CONSTRUCTOR,

LOCAL_VARIABLE

2. @Retention: 注解什么时候生效。默认时源码 java经历了那些阶段。

源码阶段-->字节码阶段--->运行阶段 SOURCE,

CLASS,

RUNTIME

3. @Documented 当生产api文档时该注解还存在。

4. @Inherited 是否运行被子类继承。

3.4.自定义注解(高级)

@RequestMapping("/hello") 因为它定义@RequestMaping注解中有属性。

@interface 注解名{

数据类型 属性名() default 默认值;

}

数据类型: 基本类型,字符串类型,枚举类型【常量】,注解类型,数组类型【必须是上面这些类型的数组】

代码展示:

public class Test {
    public static void main(String[] args) {
        Info i=new Info();
        i.name="张三";
        i.show();
    }
}
//定义好注解
//表示该注解可以使用的位置
@Target(value = {ElementType.TYPE,ElementType.METHOD})
//表示注解什么时候生效--source--class[默认字节码有效]---runtime[反射时验证]
@Retention(value = RetentionPolicy.RUNTIME)
//是否在生成api文档时存在该注解
@Documented
//子类是否能继承该注解,如果注解在定义时使用了下面这个元注解则能被子类继承。
@Inherited
@interface My{
    String value(); //如果设置default默认值,那么在使用该注解时可以不为该属性赋值。
    int age() default 15;
    String[] hobby() default {};//
}
//使用注解 如果使用注解时有且仅有一个属性没有赋值,而且该属性的名字value那么在给该属性赋值值,可以省略value,当写其他内容时,不能省略value
@My(value = "hello",hobby = "游泳")
class Info{
    public String name;
    public void show(){
        System.out.println("show================="+name);
    }
}
class Student extends Info{
}

到此这篇关于Java泛型与注解全面分析讲解的文章就介绍到这了,更多相关Java泛型与注解内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java泛型与注解全面分析讲解

本文链接: https://www.lsjlt.com/news/166025.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java泛型与注解全面分析讲解
    目录1.什么是泛型2.为何使用泛型2.1.如何定义泛型2.2.通配符2.3.受限泛型2.4.泛型接口2.5.泛型方法3.java高级--注解3.1.预定义注解3.2.自定义注解(初级...
    99+
    2022-11-13
  • Java详细分析讲解泛型
    目录1.泛型概念2.泛型的使用2.1泛型类语法2.2泛型方法语法2.3泛型接口语法2.4泛型在main方法中的使用3.擦除机制4.泛型的上界5.通配符5.1通配符的上界5.2通配符的...
    99+
    2022-11-13
  • 详细全面解析Java泛型
    1.概述 作为一个面向对象的编程语言,Java可以通过实现一些类,作为我们各种需求的一个模板,方便我们的使用。但有时候,这个类的范围可能比我们想要的范围要大,我们只想限定于满足类的某...
    99+
    2022-11-13
  • java注解的全面分析
    全面解析java注解Java中的常见注解 a.JDK中的注解    @Override 覆盖父类或者父接口的方法    @Deprecated 表示方法已经过时 &nbs...
    99+
    2023-05-31
    java 注解 ava
  • 史上最全图文讲解Java泛型
    目录前言一:泛型本质二:为什么使用泛型三:如何使用泛型1、泛型类2、泛型接口3、泛型方法四:泛型通配符五:泛型中KTVE的含义六:泛型的实现原理七:关于泛型数组要提一下八:最后前言 ...
    99+
    2022-11-13
  • Go1.18新特性之泛型的全面讲解
    目录序1. 一切从函数的形参和实参说起2. Go的泛型3. 类型形参、类型实参、类型约束和泛型类型3.1 其他的泛型类型3.2 类型形参的互相套用3.3 几种语法错误3.4 特殊的泛...
    99+
    2023-03-09
    Golang 泛型使用 Golang 泛型 Go 泛型
  • Java@GlobalLock注解详细分析讲解
    目录GlobalLock的作用全局锁为什么要使用GlobalLock工作原理GlobalLock的作用 对于某条数据进行更新操作,如果全局事务正在进行,当某个本地事务需要更新该数据时...
    99+
    2022-11-21
    Java @GlobalLock Java @GlobalLock注解
  • Java深入浅出讲解泛型与包装类
    目录1、什么是泛型2、泛型的语法3、泛型的上界4、通配符(1)通配符的上界(2)通配符的下界5、包装类1、什么是泛型 泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指...
    99+
    2022-11-13
  • GoLang函数与面向接口编程全面分析讲解
    目录一、函数1. 函数的基本形式2. 递归函数3. 匿名函数4. 闭包5. 延迟调用defer6. 异常处理二、面向接口编程1. 接口的基本概念2. 接口的使用3. 接口的赋值4. ...
    99+
    2023-01-28
    Go函数 Go面向接口
  • java注解与元注解实例分析
    这篇文章主要介绍“java注解与元注解实例分析”,在日常操作中,相信很多人在java注解与元注解实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”java注解与元注解实例分析”的疑惑有所帮助!接下来,请跟...
    99+
    2023-06-30
  • Java全面细致讲解类与对象
    目录类和对象的关系类和对象的实例化static关键字private实现的封装构造方法this关键字代码块匿名对象小结类和对象的关系 类就是一类对象的统称。对象就是这一类具体化的一个...
    99+
    2022-11-13
  • 怎么解析Java泛型与等价实现
    怎么解析Java泛型与等价实现,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。说起泛型,也许有很多人不明白或是不懂。泛型是Java SE 1.5的新特性,泛型的本...
    99+
    2023-06-17
  • 一文带你了解java中的泛型、反射与注解
    一文带你了解java中的泛型、反射与注解?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。泛型擦除泛型擦除: 泛型只在编译时期有效,编译后的字节码文件中不存在泛型信息。声明泛型...
    99+
    2023-05-31
    java 反射 泛型
  • 29个CSS面试题的讲解与分析
    这篇文章给大家分享的是有关29个CSS面试题的讲解与分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。CSS是层叠样式表( Cascading Style Sheets )的缩写,是一种样式表语言,用于描述以 H...
    99+
    2023-06-14
  • java JVM方法分派模型静态分派动态分派全面讲解
    目录前言1. 知识储备1.1 分派1.2 变量的静态类型 & 动态类型2. 静态分派a. 变量的静态类型 发生变化 的情况b. 静态分派的优先级匹配问题3. 动态分派4. 二...
    99+
    2022-11-13
  • Mysql的DQL查询操作全面分析讲解
    目录DQL简介具体操作数据准备简单查询运算符条件查询排序查询聚合查询null值的处理分组查询分页查询insert into select语句总结DQL简介 概念:DQL(data query language)...
    99+
    2022-12-03
    MysqlDQL查询 Mysql语句查询 MysqlDQL
  • JavaScript错误处理机制全面分析讲解
    目录1. Error 实例2. 原生错误类型2.1 ReferenceError2.2 SyntaxError2.3 TypeError2.4 RangeError2.5 URIEr...
    99+
    2022-11-13
    JavaScript错误处理机制 JS错误处理
  • Java栈与队列超详细分析讲解
    目录一、栈(Stack)1、什么是栈?2、栈的常见方法3、自己实现一个栈(底层用一个数组实现)二、队列(Queue)1、什么是队列?2、队列的常见方法3、队列的实现(单链表实现)4、...
    99+
    2022-11-13
  • Java依赖注入容器超详细全面讲解
    目录一、依赖注入Dependency Injection二、解析2.1 典型的配置文件2.2 配置文件所对应的Java类2.3 定义解析器三、bean工厂(根据bean定义创建bea...
    99+
    2023-01-12
    Java依赖注入容器 Java依赖注入
  • Java全面讲解顺序表与链表的使用
    目录线性表顺序表链表小结线性表 线性表 ( linear list ) 是 n 个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见 的线性表:顺序表、...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作