【问题标题】:Java 11 reflectionJava 11 反射
【发布时间】:2021-11-07 02:52:00
【问题描述】:

我需要一种通用方法来确定是否允许对对象成员进行反射访问。在 Java 8 中,如果成员是公共的并且类是公共的,则允许反射访问。在 Java 11 中,这不再适用。那么如何确定是否允许对 Java 11 中的对象成员进行反射访问?以下是一些说明问题的示例代码:

import java.lang.reflect.*;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;

public class Refl {
    public static void main(String[] args) throws Exception {
        //System.out.println(sun.security.ssl.SSLSocketFactoryImpl.class); // doesn't work
        SocketFactory sf = SSLSocketFactory.getDefault();
        SSLSocketFactory.class.getMethod("getDefaultCipherSuites").invoke(sf);
        Class cls = sf.getClass();
        System.out.println(cls);
        System.out.println(Modifier.isPublic(cls.getModifiers()));
        Method m = cls.getMethod("getDefaultCipherSuites");
        System.out.println(m);
        System.out.println(Modifier.isPublic(m.getModifiers()));
        m.invoke(sf);  // here is the issue
        System.out.println("done");
    }
}

【问题讨论】:

  • IllegalAccessException 似乎是检测它的好方法。出于好奇,您为什么需要这样做?
  • 您能否澄清一下您所指的 Java 11 更改?我不熟悉。您的代码中的问题是什么?
  • 你知道你可以做sf.getDefaultCipherSuites(),对吧?不需要反射。
  • 如果某些内容不公开,也许您应该了解如何使用公共 API 而不是绕开它?这应该使您的代码更容易且不那么脆弱。

标签: java reflection java-11


【解决方案1】:

Method 扩展 ExecutableExecutable 扩展 AccessibleObject

AccessibleObject 提供了一个名为 canAccess 的方法,您可以将其用于此目的:

import java.lang.reflect.*;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;

public class Refl {
    public static void main(String[] args) throws Exception {
        //System.out.println(sun.security.ssl.SSLSocketFactoryImpl.class); // doesn't work
        SocketFactory sf = SSLSocketFactory.getDefault();
        SSLSocketFactory.class.getMethod("getDefaultCipherSuites").invoke(sf);
        Class cls = sf.getClass();
        System.out.println(cls);
        System.out.println(Modifier.isPublic(cls.getModifiers()));
        Method m = cls.getMethod("getDefaultCipherSuites");
        System.out.println(m);
        System.out.println(m.canAccess(sf));// check here
        m.invoke(sf);  // here is the issue
        System.out.println("done");
    }
}

【讨论】:

  • 感谢您的帮助,但不,对 canAccess() 的调用本身会产生警告。
  • 代码发生了什么:docs.google.com/document/d/… -
  • @WillLin 尝试使用 --illegal-access=deny 或最新的 JDK 运行,这是默认设置
猜你喜欢
  • 2019-04-17
  • 2011-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-17
  • 2010-09-30
相关资源
最近更新 更多