您的位置:首页 > 其它

Retrofit源码分析 (二.基础知识反射认识)

2017-08-30 09:29 274 查看
反射

反射位于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源码分析。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: