反射随笔(一):反射包的结构

反射随笔(一):反射包的结构

前言:

? 源码学习基于JDK 8

一,Interface

1,结构

- java.lang.reflect.AnnotatedElement
    - java.lang.reflect.AnnotatedType
        * java.lang.reflect.AnnotatedArrayType
        * java.lang.reflect.AnnotatedParameterizedType
        * java.lang.reflect.AnnotatedTypeVariable
        * java.lang.reflect.AnnotatedWildcardType
    - java.lang.reflect.GenericArrayType
    - java.lang.reflect.GenericDeclaration
    - java.lang.reflect.TypeVariable
- java.lang.reflect.InvocationHandler
- java.lang.reflect.Member
- java.lang.reflect.Type
    - java.lang.reflect.ParameterizedType
    - java.lang.reflect.WildcardType

2,分类简介

2.1,java.lang.reflect.AnnotatedElement

? AnnotatedElement该接口代表了一个在JVM内运行的一个被注解标注的元素,可以是Class,Method,Field,Constructor,Package等,通俗来讲就好比如果你买了商品那你就是顾客,买商品就是被注解标注,顾客就好比这个类,通过这个接口的方法你就可以获取某个Method,Field,Constructor,Package等 上面的注解信息,前提是这些元素都实现了这个接口。

该接口内的方法相对来说比较常见,所以不一一介绍,只区分一下getAnnotation()和getDeclaredAnnotation()的区别,这两个方法,不同的类调用,返回结果是不同的,但是比较好总结的。对于类Class和Package来说是一样的(Package调用的就是Class的方法):

? getAnnotation() 返回该元素上的所有注解,包括从父类继承下来的(当然被继承下来的注解必须是被@Inherited元注解标记的)

? getDeclaredAnnotation() 返回该元素上的所有注解,不包括从父类继承下来的

而对于Method、Field、Constructor、Parameter来说,这两个方法返回值都是一样的,返回的都是该元素上的所有注解。

2.2,AnnotatedType、AnnotatedParameterizedType、AnnotatedTypeVariable、AnnotatedWildcardType

? 其中AnnotatedType为其他的几个的父接口,就一个方法getType() ,主要是用来获取元素上注解的类型,最明显的一个操作如下:

public class Test implements @Annotation Interface {
}
//通过AnnotatedType a = Test.class.getAnnotatedSuperclass()
//通过这个a就可以获取@Annotation这个注解

其他接口暂时不研究(个人研究的有点模糊,有弄清楚同学可以留言分享分享)

2.3,GenericArrayType

? 获取泛型数组类型,比如 List[] ,T[] 。接口中只有一个方法getGenericComponentType(), 该方法返回的就是泛型数组中泛型的类型,比如T[] 中的T,当数组是一个多维数组时,该方法只会去除最右边那一层,比如 List[] [] ,调用getGenericComponentType方法后返回的是List[]。

2.4,GenericDeclaration

? 泛型声明,实现该接口的类才可以声明泛型,而目前为止,它的子类只有三个Class、Constructor、Method。需要说的是声明泛型和使用泛型不是一回事,如图:

结果应该是挺明显的,Field上可以使用泛型,但是它却不可以主动声明泛型,如果当前类没有泛型,那么Field不可以使用泛型,但是Method和Constructor就不同,它们在类上没有泛型的情况下依然可以声明泛型。该接口只有一个方法getTypeParameters,该方法便是用来获取泛型的类型,如上图Test12 的E。

2.5,InvocationHandler

? 这个接口不介绍,JDK代理必须要使用的一个接口,基本上大家都见过

2.5,Member

? 用来记录反射对象的一些标记信息

//标记用来只获取公开的信息(只被public修饰的,包括从超类继承的)
public static final int PUBLIC = 0;
//标记用来获取所有的信息(不包括继承的),无视修饰符
public static final int DECLARED = 1;
//获取申明类
public Class<?> getDeclaringClass();
//获取名称,比如 int a = 1;中的a  public void test();中的test
public String getName();
//获取修饰符 比如 public、 static、final 等
public int getModifiers();
//是否人工合成的
public boolean isSynthetic();
2.6,ParameterizedType

? 参数化类型,也就是泛型,内部方法如下:

// 获取实际类型参数,例如:
// public Test extends Test1<String>{}  中的String
Type[] getActualTypeArguments();
// 获取声明泛型的对象类型 如:Test<T> 中的Test
Type getRawType();
// 获取所有者类型,如果有内部类时,内部类上有泛型,调用这个方法返回的便是内部类外面的那个类
Type getOwnerType();
2.7,Type

? Java语言中,所有类型的父接口

2.8,TypeVariable

? 类型变量,指的就是泛型中的类型,如Test 中的T,方法如下:

//获得该类型变量的上限,也就是泛型中extend右边的值,如 List<T extends Test> 中的Test,因为泛型可以是多个,所以返回值是数组,如果没有extends,则默认是Object
Type[] getBounds();
//获得该类型变量的声明实体,如:List<T extends Test> 中的List
D getGenericDeclaration();
//获得类型变量的名称,如:List<T extends Test> 中的T
String getName();
//该方法暂时没搞清
AnnotatedType[] getAnnotatedBounds();
2.8,WildcardType

? 通配符类型,如: ? extends classA、?super classB。方法如下:

//获取泛型表达式的上界  ? extends ClassA 中的ClassA
Type[] getUpperBounds();
//获取泛型表达式的下界  ? super ClassB 中的ClassB
Type[] getLowerBounds();

二、Class

1,结构

- java.lang.reflect.AccessibleObject
    - java.lang.reflect.Executable
        - java.lang.reflect.Constructor
    - java.lang.reflect.Field
- java.lang.reflect.Array
- java.lang.reflect.Modifier
- java.lang.reflect.Parameter
- java.lang.reflect.Proxy
- java.lang.reflect.ReflectAccess
- java.lang.reflect.ReflectPermission
java.lang.reflect.WeakCache

2,分类简介

2.1,AccessibleObject

? 先看官方解释:AccessibleObject类是字段、方法和构造函数对象的基类。它提供了在使用反射对象时将其标记为禁止默认Java语言访问控制检查的能力。当字段、方法或构造函数分别用于设置或获取字段、调用方法或创建和初始化类的新实例时,将执行访问检查(针对public、default (package)访问、protected和private成员)。

在反射对象中设置可访问标志允许具有足够特权的复杂应用程序(如Java对象序列化或其他持久性机制)以通常禁止的方式操作对象。

默认情况下,反射对象是不可访问的。

个人感觉,这个类就是设置要不要绕过jvm控制检查的,核心方法setAccessible,当我们要对反射拿到的方法进行执行或者对通过反射拿到的字段进行赋值等操作时,需要设置setAccessible为 true来绕开Java语言的控制检查能力。网上有人说是作用于权限修饰符的,比如访问private需要设置,访问public就不许要,其实这么理解是不对的,Java语言的控制检查不仅仅是对访问修饰符做检查,还会对是不是final等做检查,比如我们都知道用final修饰的变量是不可以被修饰的,如果通过反射对public final 修饰的变量赋值时同样会报错,如下图

,所以设置setAccessible(true),不仅仅是绕过访问规则,也绕过了Java语言的某种其他规则,比如被final修饰的不可变规则。

2.2 Array

? 这个类项目中一般很少用到,主要是通过这个类,调用native构建数组,这里不多分享,有兴趣的可以自己玩玩

2.3,Constructor,Field,Method,Parameter

? 这几个类大家很常用,这里也不多分享,后面详解

2.4,Executable

? 这个类是Method和Constructor公共方法抽取的共享类

2.5,Modifier

? Java语言中的所有的修饰词,采用不同的int值表示不同的修饰字,不详解

2.6,ReflectAccess和ReflectPermission

? 这两个都是反射权限相关的类,也不多分享

2.7,WeakCache

? 反射过程中的一个弱缓存,没啥特殊功能

原文地址:https://www.cnblogs.com/lx-lixiao/p/11865617.html

时间: 2024-11-08 21:40:07

反射随笔(一):反射包的结构的相关文章

Java 反射机制[Field反射]

Java 反射机制[Field反射] 1.  反射概念及功能 反射就是把Java类中的各种成分映射成相应的Java类.例如一个Java类中用一个Class类的对象来表示.一个类中的组成部分分为成员变量,方法,构造方法,包等等. Java反射机制主要提供了以下功能: 判断在运行时任意一个对象所属的类:在运行时构造任意一个类的对象:判断在运行时任意一个类所具有的成员变量和方法:在运行时调用任意一个对象的方法:生成动态代理. 2.  Field反射 以下代码将obj对象中的String类型的字段对应的

反射机制,反射的性能,如何优化?

反射机制的定义: 是在运行状态中,对于任意的一个类,都能够知道这个类的所有属性和方法,对任意一个对象都能够通过反射机制调用一个类的任意方法,这种动态获取类信息及动态调用类对象方法的功能称为java的反射机制. 反射的作用: 1.动态地创建类的实例,将类绑定到现有的对象中,或从现有的对象中获取类型. 2.应用程序需要在运行时从某个特定的程序集中载入一个特定的类.

java 反射和暴力反射 两个DEMO

该类为反射函数 获取和暴力获取ReflectPoin类中的属性 package com.tuozou.test; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class ReflectTest { public ReflectTest() { // TODO Auto-generated con

Java 反射机制[Method反射]

Java 反射机制[Method反射] 接着上一篇Java 反射机制[Field反射],通过调用Person类的setName方法将obj的name字段的Value设置为"callPersonSetNameMethod"来了解什么是Method反射.示例代码很简单,很容易理解. 可以看到Method.invoke()实际上并不是自己实现的反射调用逻辑,而是委托给sun.reflect.MethodAccessor来处理. 真正的反射是调用MethodAccessor.invoke()真

Myeclipse显示文件夹而不是包的结构

今天用Myeclipse新建工程,写了代码,发觉workspace空间显示工程下包和class都是平行结构,看的很不顺,原因有两个,第一,可能没有切换到Package workspace视图, 第二,workspace显示目录顶上右边有个小倒三角型图标,点击,然后package presentation-->Flat这样就能树形显示. Myeclipse显示文件夹而不是包的结构

以太网数据包、IP包、TCP/UDP 包的结构(转)

源:以太网数据包.IP包.TCP/UDP 包的结构 版本号(Version):长度4比特.标识目前采用的IP协议的版本号.一般的值为0100(IPv4),0110(IPv6). IP包头长度(Header Length):长度4比特.这个字段的作用是为了描述IP包头的长度,因为在IP包头中有变长的可选部分.该部分占4个bit位,单位为32bit(4个字节),即本区域值 = IP头部长度(单位为bit)/ (8*4),因此,一个IP包头的长度最长为“1111”,即15*4=60个字节.IP包头最小

Java反射机制(取得类的结构)

通过反射得到一个类中的完整的结构,就要使用java.lang.reflect包中的以下几个类: Constructor:表示类中的构造方法 Field:表示类中的属性 Method:表示类中的方法 Class类中的常用方法: 确定此对象所表示的类或接口实现的接口. public Class<?>[] getInterfaces() 取得父类 public Class<? super T> getSuperclass() 取得全部的构造方法 public Constructor<

反射机制 反射的应用 ---取得类的结构

1 取得所实现的全部接口 1 public class InstanceDemo { 2 public static void main(String[] args) { 3 Class<?> c = null; 4 try { 5 c = Class.forName("com.matto.InstanceDemo.Person"); 6 } catch (ClassNotFoundException e) { 7 e.printStackTrace(); 8 } 9 Cl

随笔-java反射

/**     * 获取class的 包括父类的                          * @param type     * @return     */    public static Field[] getClassFields(Class<?> clazz) {        List<Field> list = new ArrayList<Field>();        Field[] fields;        do{