技术标签: java
1.机制
在运行状态(动态)中对于任意一个类,都能够知道这个类的所有属性和方法
对于任意一个对象都能够调用它的任意方法和属性
2.功能
1.在运行时获取任意一个对象修饰符,泛型,父类/实现的接口/注解等
2.运行时构造任意一个类的对象
3.运行时获取任意一个类所具有的构造方法,成员变量和方法
4.运行时访问任意一个对象的成员变量和方法
3.应用
(1)通过类的全名创建类实例来使用外部用户定义的类
(2)开发类浏览器和智能IDE
(3)在测试工具中检测类的内部结构
(4)在框架开发中用于实现配置信息的处理
1.class类
java.lang.Class是所有Reflection API的切入点,是所有反射操作的入口
对于每种类型的对象java虚拟机都会实例化一个不可变的java.lang.Class实例
每个对象都是引用或者原始类型
1.java.lang.Class.java类对象
2.java.lang.reflect.Constructor.java类的构造器对象
3.java.lang.reflect.Method.java类的方法对象
4.java.lang.reflect.Field.java类的属性对象 Field字段也即成员变量
一/获取Class实例的三种方法
1.对象.getClass()
2.类型名.class
3.ClassforName()(最常用)
二/获取类的成员
java.lang.reflect.Field.java类,一个Field提供类或接口中的一个成员变量的信息,可以动态访问
public Field getDeclaredField(String name)//根据名字获取类中定义的成员变量,不包括继承父类的成员
public Field[] getDeclaredFields()//获取类中声明的所有成员变量,返回Field[]类型,不含继承父类的成员
无Declared包含继承父类的成员
访问成员变量,成员方法和构造方法的方法
1.列出所有成员的方法
2.根据名字搜索特定成员的方法
3.获取类的成员方法
4.获取类的构造方法
5.调用成员方法
//使用反射调用对象的方法
//使用反射根据方法名,和参数类型、参数数量来获取具体某个方法
Method m=c.getDeclaredMethod(methodname, Class.forName(mptypes[0]));//String.class
//方法的调用,调用o对象的m方法,方法的实际参数是mp1,mo是方法调用的返回值
Object mo=m.invoke(o,mp1);
//o.setName("xiaohong");
System.out.println(mo);
//调用了o对象名为setAge,参数有1个,类型是int型的方法,实际参数是21
m=c.getDeclaredMethod("setAge", int.class);
m.invoke(o, 21);
System.out.println(o);
/*Method m=c.getDeclaredMethod(methodname);
Object mo=m.invoke(o);
System.out.println(mo);
System.out.println(f.get(o));*/
不得不用反射
第一个参数是调用方法的类实例
(静态方法)第一个参数为null
后面几个参数是该方法的参数
6.用反射的方式给对象的属性设置值,获取对象的属性值
//使用反射访问类对象的属性(给属性设置值,获取属性的值)
Field f=c.getDeclaredField(fieldname);//根据Field名,获得Field对象
f.setAccessible(true);
f.set(o,fvalue);//o.name=“xiaolin”;使用反射给o对象的f代表的属性设置值为发value的值
System.out.println(f.get(o));//获取o对象的f属性对应的值,并输出
1.给定类的实例
2.通常情况下是因为常规方法无法设置对象的属性值才迫不得已用反射
3.这方法违反了类的封装性的设计意图,耗费额外的系统开销
7通过Constructor实例创建对象
(1)关键字new
Object o=c.newInstance();//Student o=new Student();
(2)第二种用反射创建类对象的方法,先获取具体的Constructor,再用Constructor去创建对象
Constructor con=c.getDeclaredConstructor(String.class,int.class);
//根据构造方法参数类型来获取某个构造方法
Object o1=con.newInstance("Mary",20);
//用Constructor创建类对象,相当于Student o1=new Student("Mary",20);
System.out.println(o1);
//第一种用反射创建类对象的方法,相当于调用类的无参数构造方法
方法1调用非私有的无参构造,可以抛出构造方法的异常
方法2形参是(Object… obj)调用类的任何一个构造方法。用InnovationTargetException封装异常来抛出
1.反射增加了JVM的系统开销,
2.反射允许访问私有成员,打破了封装,可能破坏可移植性。
总结:能不用就不用
Class c=Class.forName(classname);
//根据类名字符串获得类对应的Class实例
包含继承父类成员
访问对象的属性(给属性设置值,获取属性的值)
//使用反射访问类对象的属性(给属性设置值,获取属性的值)
Field f=c.getDeclaredField(fieldname);//根据Field名,获得Field对象
f.setAccessible(true);
f.set(o,fvalue);//o.name="xiaolin";使用反射给o对象的f代表的属性设置值为fvalue的值
System.out.println(f.get(o));//获取o对象的f属性对应的值,并输出
用获取的类型来进行获取修饰符
这个是获取类声明所有的成员变量返回TypeVariable<?>接口类型
继承了多个接口
方法有getName()
getTypeParameters();
格式化成字符串后getName()
super父类
类型Class接口interfaces类型Type
getGeneritcinterfaces()c
ToString()获取类的注解类型Annotation
getAnnotation()
toString()
获取类的构造函数
Constructor返回类型
getDeclaredConstructor();
toGenericString()
获取类的成员变量
Field[]返回类型(成员变量类型)
getDeclaredFields();
ToGenericString();
Method[]返回类型
getMethods();
获取类的公有方法toGener
icString()
import java.lang.reflect.TypeVariable;
import java.lang.reflect.Modifier;
Modifier/TypeVariable要import才能使用
Class可以不用import
c.getModifiers()
%n这个参数必须是一个有符号整数的指针,它存储它出现之前打印的所有字符数。
.format(" ")格式化字符串
通过调用invoke方法来执行对象的某个方法
图片源于https://www.cnblogs.com/qingchen521/p/8575761.html
一个元数据形式,提供有关程序的数据,该数据不属于程序本身,注释对于对其注释的代码的操作没有直接影响
注解的语法
@注解类型名
用途:
1.编译前:为编译器提供编译检查的依据,辅助检查代码错误或抑制检查异常。
2.编译中或发布时:给编译器提供信息生成代码或给其他工具提供信息生成文档等。
3.运行时:在运行过程中提供信息给解释器,辅助程序执行。
注解经常和反射结合起来用,多用于框架中
五个基本注解
@Override
@Deprecated
@Suppress Warnings
@Safe Varargs
@FunctionalInterface
1.Override
位置:在方法前
作用:1.表示重写父类的方法
2.如果重写有错误就报错
可以强制子类必须覆盖父类的方法
[email protected]过时的警告
since属性指定从哪个版本开始,forRemoval指定该API将来会被删除
[email protected]
抑制编译器警告
4.SafeVarargs
堆异常警告
//给一个不带泛型的对象赋给一个带泛型的变量的时候往往就会发生堆污染
堆污染警告
faltyMethod发出"堆污染警告"
1.使用@SafeVarargs修饰引发该警告的方法或构造器
[email protected](“unchecked”)修饰
3.编译时用-Xlint:varags选项
函数式接口
@FunctionalInterface
如果接口中只有一个抽象方法
该接口就是函数式接口
修饰符:@interface(自动继承java.lang.annotation.Annotation接口)@元注解
元注解负责注解其他注解
Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)
4个标准的meta-annotation类型:
[email protected]
修饰注解定义
Annotation所修饰的对象范围
取值(ElementType)有:
1.CONSTRUCTOR:用于描述构造器
2.FIELD:用于描述域
3.LOCAL_VARIABLE:用于描述局部变量
4.METHOD:用于描述方法
5.PACKAGE:用于描述包
6.PARAMETER:用于描述参数
7.TYPE:用于描述类、接口(包括注解类型) 或enum声明
8.ANNOTATION_TYPE:指定该策略的注解只能修饰构造器
[email protected]
指定Annotation被保留的时间长短
必须为value成员变量指定值、
value成员变量的值只能是下面三个
1. RetentionPolicy.CLASS
编译器将把注解记录在class文件中,当运行java程序的时候JVM不可获取注解信息,这是默认值
2. RetentionPolicy.RUNTIME
编译器把注解记录在class文件中,当运行java程序的时候,JVM可以获取注解信息,可以通过反射获取信息。
3. RetentionPolicy.SOURCE
注解保留在源代码中,编译器直接丢掉这种注解
如果需要通过反射获取注解信息,就需要将value的属性值设置为RetentionPolicy.RUNTIME的@Retention(value=RetionPolicy.RUNTIME)
public interface Testable
@Retention (RetentionPolicy.SOURCE)
public @interface Testable{}
[email protected]
用于指定被元注解修饰的注解类将被javadoc工具提取成文档
如果定义注解类的时候用了@Documented修饰,则所有使用该注解修饰的程序元素的API文档将会包含该注释说明
[email protected]
被修饰的注解将具有继承性
SpringMVC框架之拦截器
网页上每一个标签都是一个盒子每个盒子有四个属性:1.内容(content)--网页中通常指文字和图片2.填充(padding,内边距)盒子与内容之间的空隙,形象点说就像盒子内的填充物泡沫或 者其他抗震的材料.内边距会增加盒子的大小3.边框(border):盒子本身4.边界(ma
http://acm.hdu.edu.cn/showproblem.php?pid=4082Hou Yi's secretTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3006 Accepted Submissi
文章目录三种画布渲染模式Canvas ScalerConstant Pixel SizeScale With Screen SizeConstant Physical SizeCanvas GroupUI 自适应原理解决方法三种画布渲染模式Screen Space - Overlay(屏幕控件 - 覆盖模式)多用于 3D 游戏画布会填满整个屏幕空间,并将画布下面的所有的 UI 元素置于...
CSS 预处理器技术已经非常的成熟了,而且也涌现出了越来越多的 CSS 的预处理器框架。本文便总结下 Sass、Less CSS、Stylus这三个预处理器的区别和各自的基本语法。1.什么是 CSS 预处理器CSS 预处理器是一种语言用来为 CSS 增加一些编程的的特性,无需考虑浏览器的兼容性问题,例如你可以在 CSS 中使用变量、简单的程序逻辑、函数等等在编程语言中的一些基本技巧
题目描述:写出一个程序,接受一个由字母、数字和空格组成的字符串,和一个字符,然后输出输入字符串中该字符的出现次数。(不区分大小写字母)数据范围: 1<=n<=1000输入描述:第一行输入一个由字母和数字以及空格组成的字符串,第二行输入一个字符。输出描述:输出输入字符串中含有该字符的个数。(不区分大小写字母)示例1输入:ABCabcA输出:2str1 = input().upper()str2 = input().upper()num = 0for word in str
四年级下册,使用的是新版教材,所以造成网络资源比较少,所以我们尽可能发挥周围力量,找到教学设计、课件、课本。随后进行集体教研,先周备课,发挥集体的力量,找出重难点、易错点,再把自己找到的资源都进行整合,确定教材资源,制定教学计划。集体教研是集体的智慧,但是每个班情况又有所不同,所以我们还要结合班级情况进行备课,制定教学设计,而网络授课和班级授课不同,这对我们来说更是一个巨大的考验,没有师生互动,要...
android培训、java培训、期待与您交流!TCP传输Socket和ServerSocket,实现了两台机器间的套接字端点,绑定本机IP地址。建立客户端和服务端,客户端对应的对象是Socket,服务端对应的对象是ServerSocket。 //客户端部分publicclassCl...
多表题目:列出每一个部门中年纪最大的员工姓名,部门名称selectname,dept_name,agefromdeptRIGHTJOINempeondept.dept1=e.dept2where(selectcount(*)fromempemWHEREem.age>e.ageande.dept2=em.dept2)<1;查找字符长度...
取消普通域用户将计算机加入域的权限普通域用户默认能够将10台计算机加入到域。如果考虑安全因素,您可能需要更改默认设置。一般域内建立的用户默认都是Domain Users组里的。您会发现发现该组的用户居然可以有加入一台计算机到域内的权限。那下面的情况如何解决:一个用户用家里的笔记本接入单位网络,用别人的账户加入到域中,拷贝走域内的一些资料 。有没...
知识的学习是越学越不会,越学发现的"黑洞"和自己的欠缺就会越多,所以一直报以心虚的状态来学,可能理解多年的东西他变化了,或者当初就没有理解的彻底,而不自知.Pgbounc...
预测编码,顾名思义预测就是利用前面的一个或者多个信号对下一个信号进行预测。预测编码就是根据离散信号之间存在的一定相关性特点进行预测,不同的是预测编码是对实际值与预测值的差值进行编码。如果预测的足够准确,那么误差信号就会很小,这样需要的码位也会大大减少,达到数据压缩的目的。举个例子:收端解码时预测过程与发端相同,预测器也相同,收端输出的信号是发端的近似值,两者误差是:Ps:每行最开始的几个像素无法预测,需要其他的编码方式编码有损的预测编码—DPCM编码预测编码是一种有损编码。所谓的