【问题标题】:Is there a simple way to add a class to java.lang有没有一种简单的方法可以将类添加到 java.lang
【发布时间】:2013-08-02 13:50:49
【问题描述】:

有没有一种简单的方法可以将我自己的类添加到 java.lang(在桌面应用程序的上下文中,而不是 applet/servlet 的上下文中)。这个想法是访问一些被愚蠢地声明为包私有的方法(例如 Integer.getChars(...),我不想复制所有这些代码)。

在我的类加载时,只需在 java.lang 包中声明一个类就会触发一个 SecurityException。

我知道我可以解压缩 rt.jar 并在那里添加我的类,但我正在寻找一种不需要修改已安装 JRE 的方法。

编辑:我忘了提到我希望 直接 访问这些方法,而不是像反射这样的迂回迂回访问方法。目标是进行像 Integer.getChars(int, index, chars) 这样的调用,不仅 compile 而且在运行时正常execute

【问题讨论】:

  • 老实说,我希望不要 :-) 现在,说真的,如果有人声明一个方法包是私有的而不是公共的,你认为强行使用那个方法是个好主意吗,很清楚方法可能会在下一个版本或之后的版本中消失?
  • 虽然他们可能会失望,但我想要访问的方法很可能不会很快消失。而且我完全清楚,我弄乱 JRE 的非公开部分是在自找麻烦。
  • “弄乱 JRE 的非公开部分” 抱歉,我破解了那个……现在,说真的,你不认为有理由让他们包私有?当然......你总是有反思......这通常是一个坏主意。权力大,责任大。
  • 不确定,但在 rt.jar 中添加任何内容会违反 Java 许可条款吗?
  • @Gamb “现在,说真的,你不认为有理由将它们设为私有吗?”。当然,他们不希望为了兼容性而必须保证这些呼唤的存在。不多也不少。

标签: classloader java


【解决方案1】:

您可以使用Java Reflections 完成此操作

Class<Integer> clazz = Integer.class;
Method m = clazz.getDeclaredMethod("getChars", int.class, int.class, char[].class);
m.setAccessible(true);
m.invoke(new Integer(1), 0, 0, new char[] {'1'});
// OR
//m.invoke(null , 0, 0, new char[] {'1'}); since getChars method is static and doesn't require an instance

【讨论】:

  • 你打败了我几秒钟 :)。现在,方法是静态的,invoke的第一个参数可以是null
  • 我的错,应该直接写调用方法。使用反射违背了目的 - 避免开销和可能的垃圾创建。不过,这是一个很好的答案。
【解决方案2】:

可以使用非标准的“-Xbootclasspath/p:”参数(Oracle VM)将类添加到受引导类加载器的 SecurityManager 保护的包中。 以这种方式添加的类是“受信任的”,并且由于它们在搜索顺序方面位于 rt.jar 之前,因此这也可以用于替换 中定义的类JRE。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-18
    • 2011-03-08
    • 2010-09-06
    相关资源
    最近更新 更多