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
  1. 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源码分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值