Android知识进阶(遥远的重头开始)随笔-生活工作点滴

Android-自定义注解-反射基础

2019-07-10  本文已影响0人  MonkeyLei

Let’s go

上一章Android-自定义注解-注解基础-自定义注解我们基本上入门了这个注解的基本的东西,具体用途我们还需要学了反射之后就大概有个印象了。然后就可以尝试去使用反射做一些事情,想想butterknife….

认识一下

什么事反射?反射有什么用?我们一起来了解下相关资料…

什么事反射(来自百度百科)

image

先了解这点就行。就是可以获取一个类的属性,方法等信息,感觉就是说你可以不用知道那个类到底有什么属性,什么方法,我们就获取所有的属性和方法,然后可以去invoke方法,获得各种定义的变量。

举个例子(下面方法你可以获取到testTv2这个变量,可以获取到onCreate、clickView等方法信息):

public class MainActivity extends AppCompatActivity {
    public TextView testTv2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void clickView(){

    }
}

知道就行。后面看看怎么操作这个东东。另外了解下一些知识点(来自百度百科)

image

阅读一下还是挺有意思的!

反射有什么用?

逆向代码 ,例如反编译
与注解相结合的框架 例如Retrofit
单纯的反射机制应用框架 例如EventBus 2.x
动态生成类框架 例如Gson

举个简单例子:加载游戏可能会涉及到高、低、中帧率模式,一般进入游戏你可以用switch, if等判断,
你也可以用利用类名称产生一个加载实例对象,进而渲染不同的。比如你的渲染类有HighRender, LowRender,
 MiddleRender三个渲染类。你可以Class.forName("xxxRender").newInstance()产生一个渲染对象。
紧紧几行代码就可以搞定!貌似酷酷滴...

说点不好的,其实反射动态生成对象的时间有可能比你直接生成的时间慢很多(我之前利用反射findviewbyid发现比直接findviewbyid慢40倍,纳秒级! 还好是纳秒级,不然没法玩了….但是这样也暴露了单纯的反射某些情况获取不是高效的。所以我之前有提到说butterknife不是单纯的反射….理解如果有偏差,后面我们再来更正,学习总是会有不对的地方-实践出真知)

来简单实践下

我们就简单看看反射有哪些方法供我们使用,主要是java.lang.Class,以及java.lang.reflect和两个东东!!!

java.lang.Class和java.lang.reflect

我们想要获取一个类的属性,方法等,就需要Class这个类,这个类获取的属性(filed、method等),然后想要获取具体的method的名称等就需要java.lang.reflect这个包里面很多相关的类,进而通过类具体的方法获取具体的属性值。
看下java.lang.Class相关api,你就大体了解了咯….

image image

看下java.lang.reflect,你就可以利用获取的file, method等对象去调用具体的方法获取值。

image

So,到这里我们基本知道了,原来可以这样的。那具体我们还是来段测试代码吧,我们就搞个java工程就行,不用非得搞android工程….或者Android工程里面随便新建一个测试类,搞个void main(String[] args)函数就可以运行了塞! (有些测试之前有了解,所以顺便调皮一下….看看,还有些无聊的测试,喵喵)

package com.test.com.mylibrary;

public class TestReflect2 {
    private int dontfuck = 0;
    public void setDontfuck(int _dontfuck){
        this.dontfuck = _dontfuck;
    }
}
package com.test.com.mylibrary;

import android.util.Log;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class TestReflect {
    private int dontfuck = 0;
    public void setDontfuck(int _dontfuck){
        this.dontfuck = _dontfuck;
    }
    public static void main(String[] args){
        try {
            ///< 这个地方要全路径...com.test.com.mylibrary.TestReflect2
            TestReflect2 testReflect2 = (TestReflect2)Class.forName("com.test.com.mylibrary.TestReflect2").newInstance();
            ///< 只能获取public的
            Field[] fields =  testReflect2.getClass().getFields();
            long firstTime = System.nanoTime();
            for ( int i = 0; i < fields.length; ++i){
                System.out.println("field'name = " + fields[i].getName());
            }
            System.out.println("循环time1=" + (System.nanoTime() - firstTime));
            firstTime = System.nanoTime();
            ///< 这种遍历效率更好,后空再琢磨....
            for ( Field field : fields){
                System.out.println("field'name = " + field.getName());
            }
            System.out.println("循环time2=" + (System.nanoTime() - firstTime));

            ///< 可以获取private的....
            fields =  testReflect2.getClass().getDeclaredFields();
            for ( int i = 0; i < fields.length; ++i){
                System.out.println("delared field'name = " + fields[i].getName());
            }
            ///< 获取所有的,包括继承来的public版本的?? 这个地方可能涉及到class声明一个类之后有哪些变化的机制,有空可以研究下...
            Method[] methods = testReflect2.getClass().getMethods();
            for (Method method : methods){
                System.out.println("method'name = " + method.getName());
            }
            ///< 获取自己声明的-这样方法要少一点
            methods = testReflect2.getClass().getDeclaredMethods();
            for (Method method : methods){
                System.out.println("delared method'name = " + method.getName());
            }
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

看结果:

image

可以看一看哟,少年。还是有点意思的哈,有什么不明白的可以看看api文档….api

反射还有很多东西

基础我们到这里,后面继续深入一下下看看Android里面我们怎么搞~~~嗖嗖的…下雨了,记得照顾好记几个…

上一篇下一篇

猜你喜欢

热点阅读