java反射笔记

本文最后更新于:2025年2月18日 下午

反射

修饰符返回值

虚拟机规范表4.1、4.4、4.5和4.7中的访问修饰符标志常量

修饰符类型 修饰符名称 标志值(十进制) 标志值(十六进制)
PUBLIC 公共 1 0x00000001
PRIVATE 私有 2 0x00000002
PROTECTED 保护 4 0x00000004
STATIC 静态 8 0x00000008
FINAL 不可变 16 0x00000010
SYNCHRONIZED 同步 32 0x00000020
VOLATILE 可变 64 0x00000040
TRANSIENT 非序列化 128 0x00000080
NATIVE 本地 256 0x00000100
INTERFACE 接口 512 0x00000200
ABSTRACT 抽象 1024 0x00000400
STRICT 严格浮点运算 2048 0x00000800

源码出处:package java.lang.reflect.Modifier;

虚拟机规范表4.1、4.4、4.5和4.7中的访问修饰符标志常量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/*
* Access modifier flag constants from tables 4.1, 4.4, 4.5, and 4.7 of
* <cite>The Java&trade; Virtual Machine Specification</cite>
*/

/**
* 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;

推荐写法

注意:当有多个不同种类的修饰符时,实际返回值为多个修饰符的值相加的和

比如方法:

1
2
3
4
5
6
//简单示例方法
public synchronized String getName() {
return name;
}
//获取方法修饰符(打印的主要代码)
System.out.println(method.getModifiers());

这个方法的修饰符返回值就是 33,即 public + synchronized : 1 + 32 = 33

直接获取修饰符返回值不直观,我们更推荐这样获取修饰符:

1
2
3
4
5
//推荐获取方法修饰符的写法
System.out.println(Modifier.toString(method.getModifiers()));

//控制台输出
public synchronized

方法源码出处:package java.lang.reflect.Modifier;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public static String toString(int mod) {
StringBuilder sb = new StringBuilder();
int len;

if ((mod & PUBLIC) != 0) sb.append("public ");
if ((mod & PROTECTED) != 0) sb.append("protected ");
if ((mod & PRIVATE) != 0) sb.append("private ");

/* Canonical order */
if ((mod & ABSTRACT) != 0) sb.append("abstract ");
if ((mod & STATIC) != 0) sb.append("static ");
if ((mod & FINAL) != 0) sb.append("final ");
if ((mod & TRANSIENT) != 0) sb.append("transient ");
if ((mod & VOLATILE) != 0) sb.append("volatile ");
if ((mod & SYNCHRONIZED) != 0) sb.append("synchronized ");
if ((mod & NATIVE) != 0) sb.append("native ");
if ((mod & STRICT) != 0) sb.append("strictfp ");
if ((mod & INTERFACE) != 0) sb.append("interface ");

if ((len = sb.length()) > 0) /* trim trailing space */
return sb.toString().substring(0, len-1);
return "";
}

补充:源码中定义的其他常量信息

未(尚未)在公共API中公开的位,因为它们对字段和方法有不同的含义,并且没有区分这类中两者的方法,或者因为它们不是Java编程语言关键字

1
2
3
4
5
6
7
8
9
10
// Bits not (yet) exposed in the public API either because they
// have different meanings for fields and methods and there is no
// way to distinguish between the two in this class, or because
// they are not Java programming language keywords
static final int BRIDGE = 0x00000040;
static final int VARARGS = 0x00000080;
static final int SYNTHETIC = 0x00001000;
static final int ANNOTATION = 0x00002000;
static final int ENUM = 0x00004000;
static final int MANDATED = 0x00008000;

VARARGS

在Java中,varargs是一种修饰符,它允许方法接受数量可变的参数。这是通过在参数列表中最后一个参数类型后面加上省略号(...)实现的。

VARARGS修饰符在Java中并不存在,这可能是你误解了varargs的概念。在Java中,varargs修饰符是通过在方法参数列表中的最后一个参数类型后面加上...来实现的。

以下是一个使用varargsJava方法的例子:

1
2
3
4
5
6
7
8
9
10
11
public class VarargsExample {
public static void printVarargs(String... varargs) {
for (String str : varargs) {
System.out.println(str);
}
}

public static void main(String[] args) {
printVarargs("Hello", "World", "Java");
}
}

在上述代码中,printVarargs方法接受一个可变参数,即一个字符串数组。在main方法中,我们调用printVarargs方法并传递了三个字符串作为参数。

注意:varargs只能应用于最后一个参数,而且方法中只能有一个varargs参数。

SYNTHETIC

SYNTHETICJava字节码中的一个修饰符,它表示该字段或方法并非由用户代码显式声明,而是由编译器自动生成的。例如,内部类的引用到外部类的实例会被标记为SYNTHETIC字段。

如果你在查看Java类文件时看到带有SYNTHETIC标记的字段或方法,通常意味着它是由编译器自动生成的,并不需要用户手动编写。

解决方法:

  1. 如果你在分析或者调试代码时遇到了带有SYNTHETIC标记的成员,可以理解这些成员是由编译器添加的,通常不需要用户干预。
  2. 如果你正在使用反射API来访问这些成员,并且想要确保只访问用户定义的字段和方法,可以通过检查成员的isSynthetic()方法来过滤这些自动生成的成员。
  3. 如果你是Java字节码的修改者或生成者,确保不要错误地生成了SYNTHETIC标记,除非你有特殊的需求需要让这部分代码对编译器可见。

MANDATED

MANDATEDJava中用于指示JVM如何使用特定的Java类或接口的修饰符。这个修饰符通常与JNI(Java Native Interface)相关的代码或者Java平台的内部类和接口有关。它是一个由JVM内部使用的标志,并不是开发者直接可控制或使用的。

如果你在代码中看到了 MANDATED 关键字,很可能是因为你正在查看的是Java的内部类或接口,或者是由JNI代码生成的类。

如果你遇到了包含 MANDATED 关键字的错误,通常这意味着你正在尝试访问或操作一个不应该直接被用户代码访问或操作的Java类。解决这类问题通常需要你避免直接操作这些内部类或接口。

如果你是在阅读Java的源码或者JVM的实现时遇到了 MANDATED 关键字,你可以理解为这个类或接口是被JVM的某些特定部分或是JNI调用的,而不是普通的用户代码。

如果你需要进一步的帮助来理解如何处理特定的 MANDATED 修饰符的问题,你需要提供更多的上下文信息,例如,你正在运行的具体代码、错误信息的完整内容,或者你正在使用的Java版本和JVM实现。


java反射笔记
https://superlovelace.top/2024/06/08/反射/
作者
棱境
发布于
2024年6月8日
更新于
2025年2月18日
许可协议