为什么以下代码编译?该方法IElement.getX(String)
返回该类型IElement
或其子类的实例.类中的代码Main
调用该getX(String)
方法.编译器允许将返回值存储到类型的变量中Integer
(显然不在层次结构中IElement
).
public interface IElement extends CharSequence {
<T extends IElement> T getX(String value);
}
public class Main {
public void example(IElement element) {
Integer x = element.getX("x");
}
}
Run Code Online (Sandbox Code Playgroud)
返回类型是否仍然是一个实例IElement
- 即使在类型擦除之后?
该getX(String)
方法的字节码是:
public abstract <T extends IElement> T getX(java.lang.String);
flags: ACC_PUBLIC, ACC_ABSTRACT
Signature: #7 // <T::LIElement;>(Ljava/lang/String;)TT;
Run Code Online (Sandbox Code Playgroud)
编辑:替换String
与一致Integer
.
是否真的不可能在jar文件中隐藏某些类?
我希望不允许直接实例化类以使其更灵活.这个罐子里只能看到工厂(或立面).
除了创建两个项目之外,还有其他办法解决这个问题吗?(两个项目:第一个包含类(实现),另一个引用第一个并包含工厂;后面只引用第二个)
前段时间,我在将方法的现有代码嵌入 try-finally 块中询问如何使用 ASM 将方法的主体包装在 try-finally 块中。解决方案是访问 in 方法体开头的 try 块的标签,visitCode()
并在访问具有返回操作码 in 的指令时完成 try-finally 块visitInsn()
。我知道如果一个方法没有返回指令,则该解决方案将不起作用,如果该方法总是以异常情况离开则适用。
不过,我发现前一种解决方案有时也不适用于带有返回指令的方法。如果一个方法有多个返回指令,它将不起作用。原因是它生成了无效的字节码,因为在方法的开头添加了一个 try-finally 块,但完成了不止一个 try-finally 块。
通常(但可能取决于 javac 编译器),字节码方法包含单个返回指令,并且所有返回路径通过跳转到该指令结束。但是,使用 Eclipse 编译以下代码将导致带有两个返回指令的字节码:
public boolean isEven(int x) {
return x % 2 == 0;
}
Run Code Online (Sandbox Code Playgroud)
用Eclipse编译的字节码:
0: iload_1
1: iconst_2
2: irem
3: ifne 8
6: iconst_1
7: ireturn // javac compilation: goto 9
8: iconst_0
9: ireturn
Run Code Online (Sandbox Code Playgroud)
因此,我想知道包装方法代码的整个代码的正确方法是什么。
java instrumentation bytecode bytecode-manipulation java-bytecode-asm
我想知道为什么Java字节码的行号不连续.
例如,在下面的getter的(未列出的)第2行和第3行中会发生什么?
public java.lang.String getX();
Code:
0: aload_0
1: getfield #2; //Field x:Ljava/lang/String;
4: areturn
Run Code Online (Sandbox Code Playgroud)
我正在使用ASM框架来处理字节码.当使用树API访问方法的代码时,我也会获得这些"隐藏"指令(但是使用操作码-1).我想知道它们的用途.
我需要这个可以访问相同数据的线程同时执行而不会相互混淆,所以Thread.join()
我一直在尝试使用同步方法。问题是我根本看不到任何变化,它一直给我带来与使用它们之前相同的结果。我什至不知道我到底做错了什么,同步方法假设阻止其他同步方法在完成之前执行,对吗?希望你能给我一些关于正在发生的事情的线索。
public class ThreadSync{
public static void main(String[] args) throws InterruptedException {
//if execute properly
//output can't be other than 0
while(true) {
ChangeValue counter = new ChangeValue();
Threads t = new Threads(counter,"up");
Threads t2 = new Threads(counter,"down");
Threads t3 = new Threads(counter,"print");
t.start();
t2.start();
t3.start();
}
}
}
class Threads extends Thread{
Threads(ChangeValue obj, String act){
counter = obj;
action = act;
}
@Override
public void run() {
switch(action) {
case ("up"): counter.up(); break;
case ("down"): counter.down(); …
Run Code Online (Sandbox Code Playgroud)