判断java权限修饰符,为什么要用位与?

昨天,有个转行做java的哥们儿发我一张图,说是他在做反射练习,问我图中红色划线的部分为啥要做与运算
反射练习访问修饰符
坦白来说,我没研究过这个问题,工作这么多年也没遇到过,但有句话说得好——“源码面前,了无秘密”。
于是就下班后,打开了jdk源码,看到了Class类的getModifiers方法,如下:

    /**
     * Returns the Java language modifiers for this class or interface, encoded
     * in an integer. The modifiers consist of the Java Virtual Machine's
     * constants for {@code public}, {@code protected},
     * {@code private}, {@code final}, {@code static},
     * {@code abstract} and {@code interface}; they should be decoded
     * using the methods of class {@code Modifier}.
     *
     * <p> If the underlying class is an array class, then its
     * {@code public}, {@code private} and {@code protected}
     * modifiers are the same as those of its component type.  If this
     * {@code Class} represents a primitive type or void, its
     * {@code public} modifier is always {@code true}, and its
     * {@code protected} and {@code private} modifiers are always
     * {@code false}. If this object represents an array class, a
     * primitive type or void, then its {@code final} modifier is always
     * {@code true} and its interface modifier is always
     * {@code false}. The values of its other modifiers are not determined
     * by this specification.
     *
     * <p> The modifier encodings are defined in <em>The Java Virtual Machine
     * Specification</em>, table 4.1.
     *
     * @return the {@code int} representing the modifiers for this class
     * @see     java.lang.reflect.Modifier
     * @since JDK1.1
     */
    public native int getModifiers();

是个native方法,具体实现无从得知。于是又看了Modifer的源码,找到了线索:

  /**
     * The {@code int} value representing the {@code public}
     * modifier.
     */
    public static final int PUBLIC           = 0x00000001;

    /**
     * The {@code int} value representing the {@code private}
     * modifier.
     */
    public static final int PRIVATE          = 0x00000002;

    /**
     * The {@code int} value representing the {@code protected}
     * modifier.
     */
    public static final int PROTECTED        = 0x00000004;

    /**
     * The {@code int} value representing the {@code static}
     * modifier.
     */
    public static final int STATIC           = 0x00000008;

    /**
     * The {@code int} value representing the {@code final}
     * modifier.
     */
    public static final int FINAL            = 0x00000010;

    /**
     * The {@code int} value representing the {@code synchronized}
     * modifier.
     */
    public static final int SYNCHRONIZED     = 0x00000020;

    /**
     * The {@code int} value representing the {@code volatile}
     * modifier.
     */
    public static final int VOLATILE         = 0x00000040;

    /**
     * The {@code int} value representing the {@code transient}
     * modifier.
     */
    public static final int TRANSIENT        = 0x00000080;

    /**
     * The {@code int} value representing the {@code native}
     * modifier.
     */
    public static final int NATIVE           = 0x00000100;

    /**
     * The {@code int} value representing the {@code interface}
     * modifier.
     */
    public static final int INTERFACE        = 0x00000200;

    /**
     * The {@code int} value representing the {@code abstract}
     * modifier.
     */
    public static final int ABSTRACT         = 0x00000400;

    /**
     * The {@code int} value representing the {@code strictfp}
     * modifier.
     */
    public static final int STRICT           = 0x00000800;

该类中定义了好多修饰符对应的整型静态常量,是用16进制表示的。以0x开始的数据表示16进制,计算机中每位的权为16,即(bai16进制)10 = (10进制)1×16
进制转换的算法就是“加权求和”来实现。

Modifier类中定义的常量
而计算机中,数据都是二进制存储的,对于java中的int,是用四个字节来存储的。一个字节由8位组成,所以这些int值用二进制表示的话,如下图:
位与运算的结果
另外,还要搞清楚“&”运算,它并不只是比“&&”缺少了逻辑短路的功能,它还具有位与的功能。
位“与”运算的运算规则:只有两个数的二进制同时为1,结果才为1,否则为0。(负数按补码形式参加按位与运算)
即 0 & 0= 0 ,0 & 1= 0,1 & 0= 0, 1 & 1= 1。
例:3 &5 即 00000011 & 00000101 = 00000001 ,所以 3 & 5的值为1

所以,到此为止,就搞清楚了文章开头那个疑问。拿着getModifiers的返回值跟任何修饰符对应的int去做位与运算,要么结果是0(表示没有包含这个修饰符),要么结果是这个修饰符的int值(表示包含了这个修饰符)。

之所以用不同的位状态来区分不同的修饰符,是因为计算机是用二进制来存储数据的,位运算的效率更高

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页