当前位置: 首页 > news >正文

JAVA知识点全面总结6:泛型反射和注解

六.JAVA知识点全面总结6泛型反射和注解

1.什么是泛型?可以用在哪里?

2.泛型擦除机制是什么?为什么擦除?

3.通配符是什么?作用是什么?

未更新

1.注解是什么?有什么用?

2.注解的自定义和实现机理是什么?

3.JAVA编译过程是什么?

未更新

1.什么是反射?反射的用处?

2.反射的结构?

3.反射在编译和运行时的理解

未更新

未更新

六.JAVA知识点全面总结6泛型反射和注解

1.什么是泛型?可以用在哪里?

①编译器行为

  • 编译器可以对泛型参数进行检测,增强代码的可读性或稳定性。

②用法

  • 泛型类: public class Person<T>{ }
  • 泛型接口:public interface Person<T>{}
  • 泛型方法:public static <E> void print(E[ ] array){}

③项目中

  • 通用的返回结果
  • 工具类

④泛型代码

  • 通用的返回结果
package fanxingtest;public class CommonResult<T> {private String code;//返回状态码private T data;//返回数据private String message;//返回信息public CommonResult(String code, T data, String message) {this.code = code;this.data = data;this.message = message;}public String getCode() {return code;}public T getData() {return data;}public String getMessage() {return message;}public void setCode(String code) {this.code = code;}public void setData(T data) {this.data = data;}public void setMessage(String message) {this.message = message;}@Overridepublic String toString() {return "CommonResult{" +"code='" + code + '\'' +", data=" + data +", message='" + message + '\'' +'}';}
}

2.泛型擦除机制是什么?为什么擦除?

①泛型擦除机制

  • 用于编译器类型检查,编译时擦除信息(编译器行为)
  • 不是真的泛型,为了兼容老版本,故引入泛型机制但不创建新的类型

②泛型擦除机制简介

  • List<T> 编译器擦除为 List
  • E[ ] Array 编译器擦除为 Object[] Array
  • 可通过反射调用方法来存其他类型(证明是编译时行为),例如List<Integer>通过反射可以存储String类型的变量

③编译过程

  • java编译器先检查泛型的类型,然后擦除类型,再编译

④泛型使用限制

  • 泛型参数不能传入基本数据类型,需要时Object的子类(擦除为Object)
  • 不能用static修饰泛型类中变量或方法(泛型),但可以在静态方法中加入泛型变为泛型方法。
    原因是能否通过类.方法调用。如果是泛型类中的静态成员变量,那么调用类.方法仍然确定不了泛型变量。如果是静态方法中加入泛型,那么类.方法也可确定泛型变量。
  • 区分泛型类中的方法和静态泛型方法
    Class Person<T> {static T eat(){ }}泛型类中的静态方法不可行
    Class Person<T>{static <k> void eat(K a){ }}泛型类中的静态泛型方法可行

⑤代码示例

  • 泛型擦除机制检验
package fanxingtest;import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Iterator;public class CaChuTest {public static void main(String[] args) throws Exception{HashSet<Integer> integers = new HashSet<>();integers.add(1);//得到hashset中的数为1System.out.println(integers.iterator().next());//利用反射插入String类型的数//此时输出1,"abc",故验证泛型是擦除类型的//注意泛型获得方法对象要加入参数(add是泛型T的方法,运行时擦除为Object类型)Class aClass = integers.getClass();Method add1 = aClass.getDeclaredMethod("add",Object.class);add1.invoke(integers,"abc");Iterator iterator = integers.iterator();while(iterator.hasNext()){System.out.println(iterator.next());}}
}
  • 泛型类的静态方法和静态泛型方法
package fanxingtest;public class StaticFanxinTest {}
class People<T>{//编译器报错static T data;//编译器报错static T print(){System.out.println("你好");return T t;}//编译器可运行static <K> void print(K k){System.out.println("你好"+k);}
}

3.通配符是什么?作用是什么?

①通配符使用与子类泛型不能赋值给父类泛型,解决多态不能用于泛型。

List<People> = List<Man> 编译不过 子类泛型不能赋值给父类泛型
List<?> = List<Man> 利用通配符 编译过

②对比

  • T 声明变量 类或方法 Object泛型擦除
  • ?不能声明 <?> 捕获类型

③通配符的使用

  • ? extends A 赋值A或A的子类 可读不可写(子类可能单独的结构)
  • ? super B 赋值B或B父类 可写可读(结构都有)
  • 注意:赋值时通配符在左,变量在右
  • 注意:泛型类型相同,类可使用多态

④代码解释

package fanxingtest;import java.util.*;public class TongPeiFuTest {public static void main(String[] args) {//泛型相同,类不同为子类父类,可以多态HashSet<Integer> integers = new LinkedHashSet<Integer>();//类相同,泛型为子类父类不可以多态,编译出错LinkedHashSet<Exception> integers1 = new LinkedHashSet<RuntimeException>();//类相同,使用通配符,编译过LinkedHashSet<?> integers2 = new LinkedHashSet<RuntimeException>();//通配符Set<? extends HashSet> ext = null;Set<? super HashSet> sut = null;Set<Set> c = null;Set<HashSet> d = null;Set<LinkedHashSet> e = null;ext = c;//编译不过 必须是子类或同级ext = d;//编译过ext = e;//编译过sut = c;//编译过sut = d;//编译过sut = e;//编译不过,必须是父类或同级//可读不可写ext.add(new HashSet());//编译不过Iterator<? extends HashSet> iterator = ext.iterator();iterator.next();//可写可读sut.add(new HashSet());Iterator<? super HashSet> iterator1 = sut.iterator();iterator1.next();}
}

未更新

1.注解是什么?有什么用?

①注解

  • 注解用于修饰类,方法,变量,提供在编译或运行时使用

②时间

  • 编译器扫描
    @override 编译器检查是否重写
    @data 编译器加入代码
  • 运行期反射处理
    @component 通过反射处理具体逻辑(处理器)

③定义

  • 系统定义注解
    @override
    @deprecated
  • 自定义注解

④元注解(注解的注解)

  • @Retention 声明生命周期(自定义注解一般声明为Runtime)
  • @Target 声明作用的目标
  • @Documented 添加信息到文档
  • @Inherited 子类自动继承此注解的注解

2.注解的自定义和实现机理是什么?

①@overide

  • 功能:重写的方法
  • JVM:在字节码层面实现了该功能

②自定义注解

  • 自定义注解
  • 实现注解处理逻辑(注解处理器:利用反射处理注解)
  • javac注册注解处理器为jvm处理器(会在运行时运行注解处理器)

③代码

  • 注解实现检查年龄大于10的孩子有几个
package annotationtest;import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Field;public class CheckAgeTest {public static void main(String[] args) {MySchoole mySchoole = new MySchoole();try {CheckAge(mySchoole);} catch (Exception e) {e.printStackTrace();}}static void CheckAge(Object o) throws Exception{Class aClass = o.getClass();int num = 0;Annotation[] annotations = aClass.getAnnotations();for(int i = 0;i < annotations.length;i++){if(annotations[i].annotationType()==Check.class){Field[] declaredFields = aClass.getDeclaredFields();for(int j = 0;j<declaredFields.length;j++){if((Integer)declaredFields[j].get(o)>=10){num++;}}}}System.out.println("班级里一共有"+num+"个大于10岁的小孩子");}
}@Retention(RetentionPolicy.RUNTIME)
@interface Check{
}@Check
class MySchoole{int age1 = 11;int age2 = 13;int age3 =9;int age4 = 12;
}

3.JAVA编译过程是什么?

  • 解析与填充符号表
  • 插入注解处理器并执行注解处理过程
  • 分析与字节码的生成

未更新

1.什么是反射?反射的用处?

①反射

  • 运行时分析类以及执行类的方法,通过反射获得任何一个类的所有属性和方法,且不知道处理的类是什么(Object)

②用处

  • 例子:不想修改代码,只想修改配置
  • 例子:代码复用,写一次注解直接多次使用且方便

③举例

  • @data lombak(注解 + 反射)
    正常写需要每次添加get set方法
    反射写,获取注解的类,动态添加get set方法生成.class文件
  • properties (配置文件 + 反射)
    正常写,每次需要直接修改代码
    反射写,每次只需要修改配置。

④代码

  • 配置+反射 动态运行代码
//注意:java获取本模块内类的结构用全限定名(包名+类名)(且类必须是public类)
//此时src/下相当于是类路径,即jvm执行class时从类路径下寻找(包名+类名)classname=annotationtest.MyMethod
methodname=saypackage annotationtest;import java.io.FileInputStream;
import java.lang.reflect.Method;
import java.util.Properties;public class PeiZhiTest {public static void main(String[] args) throws Exception{FileInputStream fileInputStream = new FileInputStream("day02/src/annotationtest/method.properties");Properties properties = new Properties();properties.load(fileInputStream);String name1 = properties.getProperty("classname");String name2 = properties.getProperty("methodname");Class aClass = Class.forName(name1);Method declaredMethod = aClass.getDeclaredMethod(name2);declaredMethod.invoke(aClass.newInstance());}}
class MyMethod{void say(){System.out.println("反射调用方法say");}void walk(){System.out.println("反射调用方法walk");}
}

2.反射的结构?

①反射

  • Class类:加载到内存的运行时类,都有一个Class的实例
  • Class类继承Object类,Class实例能表示运行的Object类

②使用的反射

  • 获取Class实例
    运行时类的静态属性Class clazz = Person.Class;
    运行时类的非静态方法 Class clazz = Person.getClass;
    Class类的静态方法 Class clazz = Class.forName(“”);
  • 创建运行时类的对象
    Object o = clazz.newInstance();
  • 获取运行时类的结构
    clazz.getDeclaredMethods();
  • 获取具体方法和具体属性对象
    Filed age = clazz.getDeclareFiled(“age”); age.set(o,12);
    Method mh = clazz.getDeclareMethod(“show”);show.invoke(o);
  • 注意
    Class的实例不能访问私有结构
    Class的实例获得方法时有形参需要加形参,不加默认无形参

3.反射在编译和运行时的理解

①多态

  • Person p = new Man()
    编译期间:允许
    运行期间:子类方法覆盖父类方法(实际上为父类引用指向子类的所有结构)

②反射

  • Object obj = clazz.newInstance();method.invoke(obj);
    编译期间:运行
    运行期间:obj实际上指向为运行时类的实例

③多态+反射

  • 即多态+反射可以让父类引用调用子类的私有结构
  • 理解:父类引用指向的就是子类的类结构(重写了方法),但是父类引用直接调用子类独有的方法编译不过,故可通过反射调用。
  • 代码
package reflecttest;import java.lang.reflect.Method;public class FuZiSiYouTest {public static void main(String[] args) throws Exception{Person p = new Man();Class aClass = p.getClass();Method eat = aClass.getDeclaredMethod("eat");//调用成功 结果为子类私有方法eat.invoke(aClass.newInstance());}
}class Person{}
class Man extends Person{void eat(){System.out.println("子类私有方法");}
}

④总结

  • 运行时类Class的实例创建的对象都为Object(编译过)
  • 在实际运行时Object指向原本类的结构,但不能直接调用(因为编译不过),需要运行时反射调用(编译过)

未更新

未更新

相关文章:

JAVA知识点全面总结6:泛型反射和注解

六.JAVA知识点全面总结6泛型反射和注解 1.什么是泛型?可以用在哪里&#xff1f; 2.泛型擦除机制是什么&#xff1f;为什么擦除&#xff1f; 3.通配符是什么&#xff1f;作用是什么&#xff1f; 未更新 1.注解是什么&#xff1f;有什么用&#xff1f; 2.注解的自定义和实…...

死代码删除(DCE,Dead Code Elimination)和激进的死代码删除(ADCE,Aggressive DCE)

死代码删除&#xff08;DCE&#xff0c;Dead Code Elimination&#xff09;和激进的死代码删除&#xff08;ADCE&#xff0c;Aggressive DCE&#xff09;死代码删除&#xff08;DCE&#xff0c;Dead Code Elimination&#xff09;DCE简介DCE基本算法激进的死代码删除&#xff0…...

询问new bing关于android开发的15个问题(前景、未来、发展方向)

前言&#xff1a;new bing是基于chat-gpt的新搜索工具&#xff0c;可以采用对话方式进行问题搜索&#xff0c;经过排队等候终于可以使用new bing&#xff0c;询问了目前我最关心的关于android开发几个问题 文章目录1.如何学好android开发&#xff1f;2.android开发能做什么?3.…...

【C++】初识类和对象

&#x1f3d6;️作者&#xff1a;malloc不出对象 ⛺专栏&#xff1a;C的学习之路 &#x1f466;个人简介&#xff1a;一名双非本科院校大二在读的科班编程菜鸟&#xff0c;努力编程只为赶上各位大佬的步伐&#x1f648;&#x1f648; 目录前言一、面向过程和面向对象初步认识二…...

EPICS S7nodave手册

第一章&#xff1a;介绍 本手册分为6章(不算次介绍部分)。第一章介绍s7nodave用于EPICS的设备支持的概念和特新。第二章描述启动一个使用s7nodave的IOC项目所需要的几步。第三章描述s7nodave支持的IOC shell命令。之后&#xff0c;第四章解释s7nodave支持的各种记录类型。最后…...

2023最新版本RabbitMQ的持久化和简单使用

上节讲了 RabbitMQ下载安装教程 &#xff0c; 本节主要介绍RabbitMQ的持久化和简单使用。 一、RabbitMQ消息持久化 当处理一个比较耗时得任务的时候&#xff0c;也许想知道消费者&#xff08;consumers&#xff09;是否运行到一半就挂掉。在当前的代码中&#xff0c;当RabbitM…...

函数式编程

函数式编程&#xff08;一&#xff09; 文章目录函数式编程&#xff08;一&#xff09;1. 前言1.1 概念2. Lambda 表达式2.1 概述2.2 基本的格式2.3 触发条件2.4 Lambda表达式2.4.1 无参无返回值2.4.2 有参无返回值2.4.3 无参数有返回值2.4.4 有参有返回值【重点】2.4.4.1 比较…...

【Java 类】001-访问修饰符、命名规范

【Java 类】001-访问修饰符、命名规范 文章目录【Java 类】001-访问修饰符、命名规范一、访问修饰符概述1、是什么2、作用作用问题3、访问修饰符有哪些4、作用对象二、访问修饰符使用演示1、类访问修饰符演示第一步&#xff1a;创建 Dog 类&#xff1a;public第二步&#xff1a…...

【C++】命名空间

&#x1f3d6;️作者&#xff1a;malloc不出对象 ⛺专栏&#xff1a;C的学习之路 &#x1f466;个人简介&#xff1a;一名双非本科院校大二在读的科班编程菜鸟&#xff0c;努力编程只为赶上各位大佬的步伐&#x1f648;&#x1f648; 目录前言一、命名空间产生的背景二、命名空…...

【AutoSAR】【MCAL】Dio

一、结构 二、功能介绍 DIO&#xff08;数字输入输出&#xff09;驱动模块主要是对端口&#xff08;Port&#xff09;&#xff0c;通道&#xff08;Channel&#xff09;和通道组&#xff08;ChannelGroup&#xff09;进行读写操作。 通道&#xff08;Channel&#xff09;&…...

瑞吉外卖——day2

目录 一、新增员工 二、查询分页数据 三、启用、禁用员工账户、编辑员工信息 一、新增员工 点击左上角新增员工 页面如下&#xff1a; 我们随便填数据 &#xff0c;点击保存&#xff0c;请求的地址如下 返回前端可以看到请求方式为Post 在employeeController中编写对应的代…...

了解java

#常见编程语言介绍 C语言 C语言 java语言 javaScript语言 PHP语言 python语言Object-C和Swift语言 C# &#xff08;c sharp&#xff09;语言 Kotlin语言 Go语言 Basic语言 #JAVA的发展 起源于1991年SUN公司GREEN项目&#xff0c;1996年JDK1.0正式发布 后被Oracle公司收购&…...

【编程实践】代码之中有创意:“我一直认为工程师世界上最具创造性的工作之一”

代码之中有创意 “我一直认为工程师世界上最具创造性的工作之一”。 文章目录 代码之中有创意一、代码可以赋予创造力1.1 代码的创造力1.2 如何发挥代码的创造力二、有创意的代码可以提高工作效率2.1 代码创意可以提高工作效率2.2 如何利用代码创意来提高工作效率三、代码创意可…...

【MySQL】表连接

一、为什么要学习 因为不合理的使用连接会导致慢查询 二、什么是连接 参与连接的表叫做 连接表&#xff0c; 连接就是把 各个连接表 进行的组合 &#xff08;笛卡儿积&#xff09;加入结果集并返回 三、连接查询 如何只是对表进行大量的连接&#xff0c;笛卡儿积作用得到的…...

2023湖南省“楚怡杯”职业技能大赛“网络安全” 项目比赛任务书

2023湖南省“楚怡杯”职业技能大赛“网络安全” 项目比赛任务书2023安徽省“中银杯”职业技能大赛“网络安全” 项目比赛任务书A模块基础设施设置/安全加固&#xff08;200分&#xff09;A-1&#xff1a;登录安全加固&#xff08;Windows, Linux&#xff09;A-2&#xff1a;Ngi…...

Android应用启动优化笔记整理

应用启动相关流程与优化 应用启动主要涉及SystemServer进程 和 app进程。 SystemServer进程负责app进程创建和管理、窗口的创建和管理&#xff08;StartingWindow 和 AppWindow&#xff09;、应用的启动流程调度等。 App进程被创建后&#xff0c;进行一系列进程初始化、组件初…...

图像bytes字节串二进制转十六进制及bytes转为图像

目录前言正文二进制与十六进制的bytes互转读取bytes为图像法1:直接写入f.read的结果法2: 转换为PIL或Numpy前言 参考&#xff1a; 8. python基础之基础数据类型–bytes - CSDN python 16进制与图片互转 - CSDN 正文 二进制与十六进制的bytes互转 bytes保存的是原始的字节(二…...

信息安全与数学基础-笔记-②同余

知识目录同余完全剩余系剩余类完全剩余系❀简化剩余系❀欧拉函数逆元&#xff01;欧拉定理 &#xff01;同余 a,b 两个数字&#xff0c;都模m&#xff0c;当两个数字模m后余的数一样即为同余。 例子&#xff1a; a bq r (mod m)&#xff0c;这里的a 和 r 就是同余 &#xff…...

网络安全法

目录正文第一章第二章第三章第四章第五章第六章 法律责任第七章 附则正文 学习网络安全应该知道网络安全法 第一章 总则 第一条: 为了保障网络安全&#xff0c;维护网络空间主权和国家安全、社会公共利益&#xff0c;保护公民、法人和其他组织的合法权益&#xff0c;促进经济…...

django框架开发部署项目

前言&#xff1a;相信看到这篇文章的小伙伴都或多或少有一些编程基础&#xff0c;懂得一些linux的基本命令了吧&#xff0c;本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python&#xff1a;一种编程语言&…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍

文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结&#xff1a; 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析&#xff1a; 实际业务去理解体会统一注…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器

拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件&#xff1a; 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...

《信号与系统》第 6 章 信号与系统的时域和频域特性

目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...