java 反射

作者: badmask | 来源:发表于2017-09-26 19:47 被阅读0次

其实原本这篇文章没啥必要,但是最近在 code review 的时候,发现这篇文章中下面这段代码有些疑问,所以就去查了查

      @SuppressLint("NewApi")
    public static boolean isNotificationEnabled(Context context) {
        AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        ApplicationInfo applicationInfo = context.getApplicationInfo();
        String pkg = context.getApplicationContext().getPackageName();
        int uid = applicationInfo.uid;
        Class appOpsClass;
        try {
            appOpsClass = Class.forName(AppOpsManager.class.getName());
            Method checkOpNoThrowMethod = appOpsClass.getMethod("checkOpNoThrow", Integer.TYPE, Integer.TYPE, String.class);
            Field opPostNotificationValue = appOpsClass.getDeclaredField("OP_POST_NOTIFICATION");
            int value = (Integer) opPostNotificationValue.get(Integer.class);
            return ((Integer) checkOpNoThrowMethod.invoke(appOpsManager, value, uid, pkg) == AppOpsManager.MODE_ALLOWED);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return false;
    }

很明显,这段代码中运用了反射,可是在AppOpsManager 类中的 checkOpNoThrow 方法代码是这样的

    /**
     * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
     * returns {@link #MODE_ERRORED}.
     * @hide
     */
    public int checkOpNoThrow(int op, int uid, String packageName) {
        try {
            return mService.checkOperation(op, uid, packageName);
        } catch (RemoteException e) {
        }
        return MODE_ERRORED;
    }

方法明明是 public ,自己还愚蠢的写了这么一段代码,看看能不能代替反射的那段代码:

appOpsManager.checkOpNoThrow("OP_POST_NOTIFICATION",uid,pkg)== AppOpsManager.MODE_ALLOWED)

运行,直接crash,报错如下:

java.lang.IllegalArgumentException: Unknown operation string: OP_POST_NOTIFICATION

仔细看了一下,AppOpsManager 类中的 checkOpNoThrow 方法,带有 hide 标签,去一探究竟~

「@hide」标签

类或 API 是否开放,是通过 doc 注释的「@hide」标签来控制的。「@hide」标签表示不对外公开 api,但是系统内部是可以使用该注释标记的接口的。
「@hide」标签注释后的类或者 API 在编译时不对外开放,但是在运行的时候这些类和 API 都是可以访问的。
解决方案:一种是使用反射的方法得到隐藏的 API;一种是使用源码编译时生成的全编译的 jar 包。

java 反射的总结

java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取以及动态调用对象的方法的功能称为 Java 的反射机制。

缺点:性能是一个问题,反射相当于一系列解释操作,通知 jvm 要做的事情,性能比直接的 java 代码要慢很多。

关于反射的参考链接:

http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html
http://www.cnblogs.com/whoislcj/p/6038511.html
https://segmentfault.com/a/1190000010162647

关于 hide 标签参考的链接:

https://stackoverflow.com/questions/17035271/what-does-hide-mean-in-the-android-source-code
http://blog.csdn.net/ouyang_peng/article/details/17288253
http://blog.sina.com.cn/s/blog_5da93c8f0101e1yj.html

相关文章

  • 博客地址

    java注解-01、java注解-02、Git面试资源java反射-01、java反射-02、java反射-03为...

  • Java反射机制入门

    Java反射机制入门 一、什么是反射 JAVA反射机制(The JAVA reflection mechanism...

  • Java基础之反射

    Java基础之—反射(非常重要)Java中反射机制详解Java进阶之reflection(反射机制)——反射概念与...

  • 反射之一

    总结内容源自一下文章粗浅看java反射机制反射机制应用实践谈谈java反射机制Java Reflection(反射...

  • 反射之二

    总结内容源自一下文章粗浅看java反射机制反射机制应用实践谈谈java反射机制Java Reflection(反射...

  • Java基础之反射

    Java基础之反射 反射基本介绍 反射的使用通过反射调用属性和方法通过反射获取配置文件 反射基本介绍 Java反射...

  • Java 反射机制

    Java 反射机制 什么是反射 Java 反射是Java语言的一个很重要的特征,它使得Java具体了“动态性”。 ...

  • 一探究竟:Java反射效率低的原因到底在哪?

    预备知识 了解 Java 反射基本用法 看完本文可以达到什么程度 了解 Java 反射原理及 Java 反射效率低...

  • 面试官说:大家都说 Java 反射效率低,你知道原因在哪里么

    预备知识 了解 Java 反射基本用法 看完本文可以达到什么程度 了解 Java 反射原理及 Java 反射效率低...

  • Java面试题之JavaSE高级

    一、Java中的反射 1.说说你对Java中反射的理解 java中的反射首先是能够获取到Java...

网友评论

    本文标题:java 反射

    本文链接:https://www.haomeiwen.com/subject/ziheextx.html