- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想使用某种编辑器打开 Java 编译器生成的字节码(Java 二进制文件),这允许我查看字节码(原始的,但人类可以理解的,采用定义的格式 here )并修改内容直接在 .class
文件。
我已经尝试过javap
公用事业。但通过javap
,我无法更改我的 .class 文件,而且它似乎没有显示原始字节代码
另外,我见过类似 JD Decompiler 的反编译器这给了我 .class
中的代码文件。但我对源代码不感兴趣,我想查看字节码。
另外,我尝试过名为 dirtyJOE 的 GUI 编辑器& JBE 。这个编辑器相当不错,达到了我一半的目的。我可以在 .class
中看到各个字段文件并编辑我的 .class
文件也是如此。但这似乎也像一个翻译器,它解码字节码并将其显示在 UI 上以便于理解。它没有向我显示原始字节代码。
是否有可能转到原始字节码?
我可能听起来很愚蠢,但我想确认这一点,正确理解 Java 编译器和 JVM。
最佳答案
可以使用javap -v
转储原始字节代码,但要以您可以编辑的格式获取类文件中的所有信息,我使用ASM。您不会使用它进行编辑的原因是;
字节码只是 Java 代码的编译版本,这毫无值(value),这就是为什么它们做同样的事情。 JVM 可以通过多种方式自由地对其进行优化,如果您想了解 JVM 的工作原理或代码的运行方式,那么理解字节码就不是很有用。
<小时/>感谢@Antimony 提出手动编写字节代码的使用建议。虽然其中一些是有效的,但它们要么相当先进,要么晦涩难懂,或者有实现相同目标的替代方法。
一些想法
throw checked exceptions without declaring them,
Thread.currentThread().stop(checkedException);
catch checked exceptions without declaring them,
if (false) throw new CheckedException();
} catch(CheckedException ce) {
use identifiers invalid in Java
有很多有效但不太有用的字符可供使用,我会使用其中一个
if( ⁀ ‿ ⁀ == ⁀ ⁔ ⁀ || ¢ + ¢== ₡)
和
for (char ch = 0; ch < Character.MAX_VALUE; ch++)
if (Character.isJavaIdentifierPart(ch) && !Character.isJavaIdentifierStart(ch))
System.out.printf("%04x <%s>%n", (int) ch, "" + ch);
由于标识符中的不可见字符导致文本向后打印,因此是有效代码。
http://vanillajava.blogspot.co.uk/2012/09/hidden-code.html
http://vanillajava.blogspot.co.uk/2012/08/uses-for-special-characters-in-java-code.html
access fields before constructor call
我很确定这会导致VerifyError(或者当我尝试时确实如此)。相反,您可以使用
Object o = Unsafe.allocateInstance(clazz); // create without calling a constructor.
call different constructors conditionally
我再次能够在对象创建和实例调用之间放置代码,但可能有一种方法可以让它工作。在 Java 中你可以这样写
MyClass mc = condition ? new MyClass(a) : new MyClass(a, b);
do exception handling on constructors.
不确定你在这里的意思,因为你可以在构造函数中捕获或抛出异常。
assign final fields more than once or not at all
您可以使用反射来代替,并为最终字段指定默认值。即字段不可能没有值。
have a strictfp constructor with nonstrictfp methods
这是一个有趣的,但不是我需要的。
use laxer type checking
字节码确实允许不同的类型检查规则,但它们很容易与不太有用的VerifyErrors发生冲突。你可以做到这一点,但恕我直言,很难做到正确。
throw exceptions from static initializer
您已经可以抛出未检查的异常,并且要抛出已检查的异常,您可以使用上面的技巧,但是我通常用 AssertionError 等包装。
use invokedynamic
您可以使用 MethodHandles,但它们在 Java 7 中相当笨重。我希望在 Java 8 中它们使用起来会更自然。
use subroutines
有趣,我还没有尝试过这个,但我不确定它们比方法调用有什么优势。
use unusual control flow
确实如此,但这更有可能使 JIT 优化器感到困惑,因此代码可能会变慢,因此可能无法为您提供您可能希望的优势。
use old super call semantics
你可以,但我不确定这有多大用处。
use thread monitors
你可以使用
Unsafe.enterMonitor();
Unsafe.exitMonitor();
Unsafe.tryMonitorEnter();
initial values for fields.
我同意编译器没有像我预期的那样使用这些,但我再次不确定如果这样做会产生什么区别。
关于java - 以可读格式打开 Java 字节代码并对其进行编辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13118851/
我正在编写一个具有以下签名的 Java 方法。 void Logger(Method method, Object[] args); 如果一个方法(例如 ABC() )调用此方法 Logger,它应该
我是 Java 新手。 我的问题是我的 Java 程序找不到我试图用作的图像文件一个 JButton。 (目前这段代码什么也没做,因为我只是得到了想要的外观第一的)。这是我的主课 代码: packag
好的,今天我在接受采访,我已经编写 Java 代码多年了。采访中说“Java 垃圾收集是一个棘手的问题,我有几个 friend 一直在努力弄清楚。你在这方面做得怎么样?”。她是想骗我吗?还是我的一生都
我的 friend 给了我一个谜语让我解开。它是这样的: There are 100 people. Each one of them, in his turn, does the following
如果我将使用 Java 5 代码的应用程序编译成字节码,生成的 .class 文件是否能够在 Java 1.4 下运行? 如果后者可以工作并且我正在尝试在我的 Java 1.4 应用程序中使用 Jav
有关于why Java doesn't support unsigned types的问题以及一些关于处理无符号类型的问题。我做了一些搜索,似乎 Scala 也不支持无符号数据类型。限制是Java和S
我只是想知道在一个 java 版本中生成的字节码是否可以在其他 java 版本上运行 最佳答案 通常,字节码无需修改即可在 较新 版本的 Java 上运行。它不会在旧版本上运行,除非您使用特殊参数 (
我有一个关于在命令提示符下执行 java 程序的基本问题。 在某些机器上我们需要指定 -cp 。 (类路径)同时执行java程序 (test为java文件名与.class文件存在于同一目录下) jav
我已经阅读 StackOverflow 有一段时间了,现在我才鼓起勇气提出问题。我今年 20 岁,目前在我的家乡(罗马尼亚克卢日-纳波卡)就读 IT 大学。足以介绍:D。 基本上,我有一家提供簿记应用
我有 public JSONObject parseXML(String xml) { JSONObject jsonObject = XML.toJSONObject(xml); r
我已经在 Java 中实现了带有动态类型的简单解释语言。不幸的是我遇到了以下问题。测试时如下代码: def main() { def ks = Map[[1, 2]].keySet()
一直提示输入 1 到 10 的数字 - 结果应将 st、rd、th 和 nd 添加到数字中。编写一个程序,提示用户输入 1 到 10 之间的任意整数,然后以序数形式显示该整数并附加后缀。 public
我有这个 DownloadFile.java 并按预期下载该文件: import java.io.*; import java.net.URL; public class DownloadFile {
我想在 GUI 上添加延迟。我放置了 2 个 for 循环,然后重新绘制了一个标签,但这 2 个 for 循环一个接一个地执行,并且标签被重新绘制到最后一个。 我能做什么? for(int i=0;
我正在对对象 Student 的列表项进行一些测试,但是我更喜欢在 java 类对象中创建硬编码列表,然后从那里提取数据,而不是连接到数据库并在结果集中选择记录。然而,自从我这样做以来已经很长时间了,
我知道对象创建分为三个部分: 声明 实例化 初始化 classA{} classB extends classA{} classA obj = new classB(1,1); 实例化 它必须使用
我有兴趣使用 GPRS 构建车辆跟踪系统。但是,我有一些问题要问以前做过此操作的人: GPRS 是最好的技术吗?人们意识到任何问题吗? 我计划使用 Java/Java EE - 有更好的技术吗? 如果
我可以通过递归方法反转数组,例如:数组={1,2,3,4,5} 数组结果={5,4,3,2,1}但我的结果是相同的数组,我不知道为什么,请帮助我。 public class Recursion { p
有这样的标准方式吗? 包括 Java源代码-测试代码- Ant 或 Maven联合单元持续集成(可能是巡航控制)ClearCase 版本控制工具部署到应用服务器 最后我希望有一个自动构建和集成环境。
我什至不知道这是否可能,我非常怀疑它是否可能,但如果可以,您能告诉我怎么做吗?我只是想知道如何从打印机打印一些文本。 有什么想法吗? 最佳答案 这里有更简单的事情。 import javax.swin
我是一名优秀的程序员,十分优秀!