性能问答>java 反射调用 private 相关>
11回复

java 反射调用 private 相关



java 反射调用时,默认超过 15 次就会生成 java 类进行调用,那么问题是这个生成的类中为什么可以调用 private 的方法。

测试代码

public class ReflectTest {

    public static void main(String[] args) throws Exception {

        Method priStr = ReflectTest.class.getDeclaredMethod("priStr");
        priStr.setAccessible(true);
        for (int i = 0; i < 16; i++) {
            String s = priStr.invoke(null).toString();
            System.out.println(s + i);
        }

        TimeUnit.SECONDS.sleep(1000000000);
    }
    

    private static String priStr() {
        return "private string";
    }
}

动态生成的类

package sun.reflect;

import com.example.demo.reflect.ReflectTest;
import java.lang.reflect.InvocationTargetException;

public class GeneratedMethodAccessor2 extends MethodAccessorImpl {
    public Object invoke(Object var1, Object[] var2) throws InvocationTargetException {
        try {
            if (var2 != null && var2.length != 0) {
                throw new IllegalArgumentException();
            }
        } catch (NullPointerException | ClassCastException var4) {
            throw new IllegalArgumentException(var4.toString());
        }

        try {
            return ReflectTest.priStr();
        } catch (Throwable var3) {
            throw new InvocationTargetException(var3);
        }
    }

    public GeneratedMethodAccessor2() {
    }
}

上述 GeneratedMethodAccessor2 类中,为什么 ReflectTest.priStr() 这个 private 的方法可以被调用。

5214 阅读
请先登录,再评论

这个主要是JVM里会做特殊处理,如果是反射的,也就是sun.reflect.MagicAccessorImpl的子类,就会不去check
可以看下Reflection::verify_field_access方法,虽然这里是访问的method,当时JVM的方法里命名了field

if (   JDK_Version::is_gte_jdk14x_version()
      && UseNewReflection
      && current_class->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) {
    return true;
  }
2年前
回复 你假笨:

magic要改为Method?

2年前回复
回复 大空翼:

嗯嗯, 是的

2年前回复
回复 黄金键盘:

确实,不过一般的编译器可能编译不过,动态修改字节码倒是可以做到这点

2年前回复
查看更多

GeneratedMethodAccessor2这个类在哪儿?怎么查看呢?

2年前

GeneratedMethodAccessor2 这个动态生成的类在怎么查看呢?

12年前
回复 dezhonger:

HSDB 或者 基于sa的自定义ClassFilter都行(https://www.iteye.com/blog/rednaxelafx-727938)

2年前回复
回复 dezhonger:

同问

2年前回复

😶同时自动生成了一个ReflectTest.priStr()的合成方法~

2年前
回复 Aladdin:

这个生成的方法是在那个类里面的呀,有什么查看的方法吗😳

2年前回复