反射修饰符 Modifier

本文介绍了Java反射中的Modifier类,它提供了解析类和成员访问修饰符的方法。详细讲解了如何通过Modifier的静态方法获取并解析整数形式的修饰符,包括isPublic、isPrivate等,并通过示例展示了如何判断成员变量的修饰符,以及如何找到具有特定组合修饰符的变量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Modifier 修饰符工具类

public class java.lang.reflect.Modifier extends Object

int java.lang.reflect.Field.getModifiers()
以整数形式返回此 Method 对象所表示方法的 Java 语言修饰符

boolean java.lang.reflect.Modifier.isPublic(int mod)
如果整数参数包括 public 修饰符,则返回 true,否则返回 false。其他方法类似

方法的修饰符获取与属性类似

JDK中的介绍:

Modifier 类提供了 static 方法和常量,对类和成员访问修饰符进行解码。修饰符集被表示为整数,用不同的位位置 (bit position) 表示不同的修饰符。表示修饰符的常量值取自于 The JavaTM Virtual Machine Specification, Second edition 的表 4.1、4.4、4.5 和 4.7。

解码方法

以上所有的修饰符都有对应的、方法声明为【public static boolean is***(int mod)】的解码方法,且方法的实现也都是类似的,比如:

public static boolean isPublic(int mod) {
return (mod & PUBLIC) != 0;
}

java中反射获取方法的修饰符

代码演示:

package com.caoguangli.reflect;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class LFrog {

	    public String name0;
	    public static String name1;
	    public static final String name2 = "name";
	    
	    public static void main(String[] args) throws NoSuchFieldException, SecurityException {
	        LFrog frog = new LFrog();
	        Class<? extends LFrog> frogClass = frog.getClass();
	        Field name0 = frogClass.getField("name0");
	        Field name1 = frogClass.getField("name1");
	        Field name2 = frogClass.getField("name2");
	        //以整数形式返回此Field 对象所表示方法的 Java 语言修饰符
	        int m0 = name0.getModifiers();// 1
	        int m1 = name1.getModifiers();// 9(1+8)
	        int m2 = name2.getModifiers();// 25(1+8+16)
	        //0 表示没有此修饰符
	        System.out.println("m2 isPublic: " + (m2&1));// 1
	        System.out.println("m2 isPrivate: " + (m2&2));// 0
	        System.out.println("m2 isStatic: " + (m2&8));// 8
	        System.out.println("m2 isFinal: " + (m2&16));// 16
	        //false 表示没有被此修饰符修饰
	        System.out.println("m2 isPublic: " + (Modifier.isPublic(m2)));// true
	        System.out.println("m2 isPrivate: " + (Modifier.isPrivate(m2)));// false
	        System.out.println("m2 isStatic: " + (Modifier.isStatic(m2)));// true
	        System.out.println("m2 isFinal: " + (Modifier.isFinal(m2)));// true
	    }
}

运行结果:

在这里插入图片描述

反射怎么知道成员是被哪些修饰符所修饰的呢?

Java针对类、成员变量、方法,有很多修饰符,例如public、private、static、final、synchronized、abstract等,这些修饰符用来控制访问权限或其他特性。

本文就用成员变量(Field)来举例说明,类以及方法的修饰符获取与成员变量是一样的。

先看一个类(通过反射,可以拿到这四个变量):

package com.caoguangli.reflect;

import java.lang.reflect.Field;

public class MyTest {
	
	public int a;
	 
    public static int b;
 
    public static final int c = 0;
 
    private int d;


public static void main(String[] args) {
 
       Class<?> clazz = MyTest.class;
 
       Field[] fields = clazz.getDeclaredFields();//获取这个类所有的成员变量
 
       for(Field field : fields) {
 
      System.out.println(field.getName());
           
 
       }
    }
}

运行结果:
在这里插入图片描述

现在,我想知道每个变量的带有哪些修饰符,或者是不是包含某个修饰符。

先看下Member接口:Member表示一个类中的成员,包括成员变量、方法、构造方法三种实现,上面用到的Field就是Member的一种。

Java文档:

java.lang.reflect

接口 Member

所有已知实现类:

Constructor(构造方法), Field(成员变量), Method(方法)
Member接口有个方法:
int getModifiers()

作为整数返回由此 Member所表示的成员或构造方法的 Java语言修饰符。

同时再看java.lang.Class类中也有同样的一个方法:

int getModifiers()

返回此类或接口以整数编码的 Java语言修饰符。

这个方法就是返回一个int型的返回值,代表类、成员变量、方法的修饰符。

代码演示:

package com.caoguangli.reflect;

import java.lang.reflect.Field;

public class MyTest {
	
	public int a;
	 
    public static int b;
 
    public static final int c = 0;
 
    private int d;


public static void main(String[] args) {
 
       Class<?> clazz = MyTest.class;
 
       Field[] fields = clazz.getDeclaredFields();//获取这个类所有的成员变量
 
       for(Field field : fields) {
       
           System.out.print(field.getName() +"->");
           System.out.println(field.getModifiers());
 
       }
       
    }
}

运行结果:
在这里插入图片描述

通过返回的int类型的值,还是很难判断这些变量有哪些修饰符。

在这里,需要用到 java.lang.reflect.Modifier 这个类。Modifier提供了很多静态方法。如public static String toString(int mod)就可以输出该整数对应的所有的修饰符。public static boolean isPublic(int mod)就可以判断该整数对应的是不是包含public修饰符。

修改上面代码,把返回的整数转换通过Modifier转换一下:

package com.caoguangli.reflect;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class MyTest {
	
	public int a;
	 
    public static int b;
 
    public static final int c = 0;
 
    private int d;


public static void main(String[] args) {
 
       Class<?> clazz = MyTest.class;
 
       Field[] fields = clazz.getDeclaredFields();//获取这个类所有的成员变量
 
       for(Field field : fields) {
         
                System.out.print(field.getName() +"->");
                System.out.println(Modifier.toString(field.getModifiers()));

       }
    }
}

运行结果:

在这里插入图片描述
通过Modifier的isPublic、isPrivate、isStatic等方法,可以判断是否包含某些修饰符,现在如果有这么一个需求,需要找到仅有public static两个修饰符的变量。

访问修饰符列表

public static final int PUBLIC = 0x00000001;
public static final int PRIVATE = 0x00000002;
public static final int PROTECTED = 0x00000004;
public static final int STATIC = 0x00000008;
public static final int FINAL = 0x00000010;
public static final int SYNCHRONIZED = 0x00000020; 同步
public static final int VOLATILE = 0x00000040; 用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最的值。
public static final int TRANSIENT = 0x00000080; 用transient关键字标记的成员变量不参与序列化过程。
public static final int NATIVE = 0x00000100;
public static final int INTERFACE = 0x00000200;
public static final int ABSTRACT = 0x00000400;
public static final int STRICT = 0x00000800;
即strictfp(strict float point 精确浮点),此关键字可应用于类、接口或方法。

把它们转换成二进制,可以看出,Modifier使用一个二进制的位来表示是否包含某个修饰符。

nativetransient
publicprotected
staticfinal
synchronized

也就是,如果是public static,对应的整数就是二进制的:1001,也就是9。如下图:

public1
static1
private1
final0

如果是public static final就是11001,也就是25。

现在如果想判断是否仅有public static两个修饰符,那么就可以判断是否field.getModifiers() == 9。

另外,我们也可以看到这里设计之精妙之处:用二进制位来标记是否包含某个修饰符。

反射详细网址:https://mp.youkuaiyun.com/mdeditor/91898501#

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值