Retrofit源码分析 (二.基础知识反射认识)
2017-08-30 09:29
274 查看
反射
反射位于java.lang.reflect包类,还是那句话,有兴趣的同学可以去瞅瞅,反正代码挺好看的。
下面主要讲的是这几个类,Method,Field,Type(子实现类GenericArrayType,WildcardType,TypeVariable,ParameterizedType)
当然有核心的类Class了,Proxy放在下一章讲。
1.java.lang.reflect.Array 动态创建数组的。示例如下:
2.java.lang.reflect.Constructor 构造函数
输出的内容是:
java.lang.reflect.Field
1.getDeclaredField(String name): 是可以获取一个类的其中一个字段
2.getDeclaredFields():是可以获取一个类的所有字段
3.getField(String name): 获取其中一个obj的字段
4.getFields(): 主要是public字段所有的
5.getType(): 获取属性声明时类型对象(返回class对象)
6.getGenericType() : 返回属性声的Type类型
7.getName() : 获取属性声明时名字
8.getAnnotations() : 获得这个属性上所有的注释
9.getModifiers() : 获取属性的修饰
10.isEnumConstant() : 判断这个属性是否是枚举类
11.isSynthetic() : 判断这个属性是否是 复合类
12.get(Object obj) : 取得obj对象这个Field上的值
13.set(Object obj, Object value) : 向obj对象的这个Field设置新值value
4.java.lang.reflect.Method
5.java.lang.reflect.Type
次章结束,下一章将Proxy讲一下之后,将讲Retrofit源码分析。
反射位于java.lang.reflect包类,还是那句话,有兴趣的同学可以去瞅瞅,反正代码挺好看的。
下面主要讲的是这几个类,Method,Field,Type(子实现类GenericArrayType,WildcardType,TypeVariable,ParameterizedType)
当然有核心的类Class了,Proxy放在下一章讲。
1.java.lang.reflect.Array 动态创建数组的。示例如下:
Object obg = Array.newInstance(String.class,5); Array.set(obg,0,"rulang0"); Array.set(obg,1,"rulang1"); String[] value = (String[])obg; System.out.println(value[1]);//输出:rulang1
2.java.lang.reflect.Constructor 构造函数
/* ********* _getConstructor()_ 和 _getDeclaredConstructor()_ 区别:********* getDeclaredConstructor(Class<?>... parameterTypes) 这个方法会返回制定参数类型的所有构造器,包括public的和非public的,当然也包括private的。 getDeclaredConstructors()的返回结果就没有参数类型的过滤了。 再来看getConstructor(Class<?>... parameterTypes) 这个方法返回的是上面那个方法返回结果的子集,只返回制定参数类型访问权限是public的构造器。 getConstructors()的返回结果同样也没有参数类型的过滤。*/ Class<?> cls = Class.forName("com.rulang.reflect.RuLangDemo"); Constructor constructor1=cls.getConstructor(new Class[]{}); System.out.println("修饰符: "+ Modifier.toString(constructor1.getModifiers())); System.out.println("构造函数名: "+constructor1.getName()); System.out.println("参数列表: "+constructor1.getParameterTypes()); Object obj = constructor1.newInstance(); // System.out.println("调用默认构造函数生成实例:"+obj.toString()); // Constructor constructor2 = cls.getConstructor(new Class[]{String.class}); Constructor constructor2 = cls.getDeclaredConstructor(new Class[]{String.class});//getConstructor System.out.println("修饰符: "+Modifier.toString(constructor2.getModifiers())); System.out.println("构造函数名: "+constructor2.getName()); System.out.println("参数列表: "+constructor2.getParameterTypes()); RuLangDemo obj2 = (RuLangDemo) constructor2.newInstance(new Object[]{"rulang"}); // Constructor constructor3 = cls.getDeclaredConstructor(new Class[]{String.class}); 此处会抱错 Constructor constructor3 = cls.getDeclaredConstructor(new Class[]{int.class}); System.out.println("修饰符: "+Modifier.toString(constructor3.getModifiers())); System.out.println("构造函数名: "+constructor3.getName()); System.out.println("参数列表: "+constructor3.getParameterTypes()); //下面的代码会抱错的,因为是私有构造函数,没法这样处理。 //RuLangDemo obj3 = (RuLangDemo) constructor3.newInstance(new Object[]{Integer.valueOf(999)});
输出的内容是:
修饰符: public 构造函数名: com.rulang.reflect.RuLangDemo 参数列表: [Ljava.lang.Class;@14ae5a5 修饰符: public 构造函数名: com.rulang.reflect.RuLangDemo 参数列表: [Ljava.lang.Class;@6d6f6e28 修饰符: private 构造函数名: com.rulang.reflect.RuLangDemo 参数列表: [Ljava.lang.Class;@135fbaa4
java.lang.reflect.Field
1.getDeclaredField(String name): 是可以获取一个类的其中一个字段
2.getDeclaredFields():是可以获取一个类的所有字段
3.getField(String name): 获取其中一个obj的字段
4.getFields(): 主要是public字段所有的
5.getType(): 获取属性声明时类型对象(返回class对象)
6.getGenericType() : 返回属性声的Type类型
7.getName() : 获取属性声明时名字
8.getAnnotations() : 获得这个属性上所有的注释
9.getModifiers() : 获取属性的修饰
10.isEnumConstant() : 判断这个属性是否是枚举类
11.isSynthetic() : 判断这个属性是否是 复合类
12.get(Object obj) : 取得obj对象这个Field上的值
13.set(Object obj, Object value) : 向obj对象的这个Field设置新值value
RuLangDemo demo=new RuLangDemo(); System.out.println(demo.getmStr());//输出:xixi Field field=demo.getClass().getDeclaredField("mStr"); field.setAccessible(true); field.set(demo,"rulang"); System.out.println(demo.getmStr());//输出:rulang1
4.java.lang.reflect.Method
1.getMethods(): 获得类的public类型的方法 2.getMethod(String name, Class[] params): 获得类的特定方法,name参数指定方法的名字,params参数指定方法的参数类型 3.getDeclaredMethods(): 获取类中所有的方法(public、protected、default、private) 4.getDeclaredMethod(String name, Class[] params): 获得类的特定方法,name参数指定方法的名字,params参数指定方法的参数类型
RuLangDemo demo=new RuLangDemo(); System.out.println(demo.getmStr());//输出:xixi Method setmStrMethod = demo.getClass().getMethod("setmStr", new Class[]{String.class}); System.out.println("修饰符: " + Modifier.toString(setmStrMethod.getModifiers())); setmStrMethod.setAccessible(true); // 修饰符 如果是私有的,必须设置这个 setmStrMethod.invoke(demo, "rulang"); // 方法调用哦 System.out.println(demo.getmStr());//输出:rulang1
5.java.lang.reflect.Type
Type是所有类型的父接口, 如原始类型(raw types 对应 Class)、 参数化类型(parameterized types 对应 ParameterizedType)、 数组类型 (array types 对应 GenericArrayType)、 类型变量(type variables 对应 TypeVariable ) 基本(原生)类型(primitive types 对应 Class),。 子接口有 ParameterizedType, TypeVariable, GenericArrayType, WildcardType, 实现类有Class。 (1)ParameterizedType 是什么样的呢? 文档上有说明哦 ParameterizedType represents a parameterized type such as Collection<String> Map<String, Object> map; Set<String> set; Class<?> class; List<String> list; 这都是ParameterizedType类型哦 Type[] getActualTypeArguments(); Map<String,Object> map 这个ParameterizedType返回的是 String 类。 Object类的全限定类名的 Type Array。 Type getRawType()Map<String,Object> map 这个 ParameterizedType 返回的是 Map 类的全限定类名的 Type Array。 Type getOwnerType();Map<String,Object> map 这个 ParameterizedType 的 getOwnerType() 为 null, 而 Map.Entry<String,String> map 的 getOwnerType() 为 Map 所属于的 Type。
public class Test { private Map<String,Object> map=null; private Map.Entry<String, String> map1=null; public static void main(String[] jiexieQi) throws Exception { Field map=Test.class.getDeclaredField("map"); Field map1=Test.class.getDeclaredField("map1"); ParameterizedType mapType = (ParameterizedType) map.getGenericType(); ParameterizedType map1Type = (ParameterizedType) map1.getGenericType(); System.out.println(mapType.getOwnerType());//输出:null System.out.println(map1Type.getOwnerType());//输出:interface java.util.Map System.out.println(mapType.getActualTypeArguments()[0]);//输出:class java.lang.String System.out.println(mapType.getActualTypeArguments()[1]);//输出:class java.lang.Object }
(2)TypeVariable:是各种类型变量的公共父接口,就是泛型里面的类似T、E。 TypeVariable,类型变量,描述类型,表示泛指任意或相关一类类型,也可以说狭义上的泛型(泛指某一类类型), 一般用大写字母作为变量,比如K、V、E等
TypeVariable 源码如下: public interface TypeVariable<D extends GenericDeclaration> extends Type { //获得泛型的上限,若未明确声明上边界则默认为Object Type[] getBounds(); //获取声明该类型变量实体(即获得类、方法或构造器名) D getGenericDeclaration(); //获得名称,即K、V、E之类名称 String getName(); }
(3)GenericArrayType:表示一种元素类型是参数化类型或者类型变量的数组类型,比如List<>[],T[]这种。
public class Test { private List<String> [] listArray; //GenericArrayType 转为Class哦 public static void main(String[] jiexieQi) throws Exception { Field listArray=Test.class.getDeclaredField("listArray"); Type typeList=listArray.getGenericType(); GenericArrayTypeImpl ty= (GenericArrayTypeImpl) typeList; ParameterizedType uu= (ParameterizedType) ty.getGenericComponentType(); System.out.println(uu.getTypeName());//输出:java.util.List<java.lang.String> }
(4)WildcardType:代表一种通配符类型表达式,类似? super T这样的通配符表达式。
源码如下: public interface WildcardType extends Type { //获得泛型表达式上界(上限) Type[] getUpperBounds(); //获得泛型表达式下界(下限) Type[] getLowerBounds(); }
public <T> void test(List<? extends classA > a){} Method method = Main.class.getMethod("test",List.class); Type[] upperBounds = null; Type[] lowerBounds = null; Type[] types = method.getGenericParameterTypes(); for(Type type : types){ Type[] actualTypeArgument = ((ParameterizedType)type).getActualTypeArguments(); for(Type t : actualTypeArgument){ WildcardType wildcardType = (WildcardType) t; lowerBounds = wildcardType.getLowerBounds(); upperBounds = wildcardType.getUpperBounds(); System.out.println("通配符表达式类型是:"+ wildcardType); if(upperBounds.length != 0){ System.out.println("表达式上边界:"+Arrays.asList(upperBounds)); } if(lowerBounds.length != 0){ System.out.println("表达式下边界:"+Arrays.asList(lowerBounds)); } } } //输出结果 通配符表达式类型是:? extends com.fcc.test.classA 表达式上边界:[class com.fcc.test.classA]
次章结束,下一章将Proxy讲一下之后,将讲Retrofit源码分析。
相关文章推荐
- Retrofit源码分析 (一.基础知识annotation认识)
- 使用Code First建模自引用关系笔记 asp.net core上使用redis探索(1) asp.net mvc控制器激活全分析 语言入门必学的基础知识你还记得么? 反射
- 反射 基础知识
- JAVA开发基础知识:解析并创建XML文件和Java的反射
- java基础知识(二)--反射机制
- 反射基础知识第一篇
- Java基础回顾 : 反射机制相关知识
- JAVA常用基础知识点[继承,抽象,接口,静态,枚举,反射,泛型,多线程...]
- 关于性能分析方面些基础知识
- 反射基础知识第二篇
- 基础知识之深入分析malloc和new
- 关于C#基础知识回顾--反射(一)
- 前端之路——第一篇:认识前端简单的基础知识
- 学习Spring必学的Java基础知识(1)----反射
- Java基础知识学习总结(四)---Hashtable和HashMap的区别与联系分析
- mysql基础知识理解和sql题讲解分析面试实战(四)之函数讲解和字符串的操作
- 黑马程序员——java基础知识篇——>反射
- 用python进行数据分析笔记1--基础知识篇
- 深度剖析WinPcap之(二)——网络分析与嗅探的基础知识(1)