Java通用接口性能

hal*_*arp 6 java generics performance interface

简单的问题,但我猜是棘手的答案.

使用通用接口会损害性能吗?

例:

public interface Stuff<T> {

    void hello(T var);
}

vs

public interface Stuff {

    void hello(Integer var);  <---- Integer used just as an example
}
Run Code Online (Sandbox Code Playgroud)

我的第一个想法是,它没有.泛型只是语言的一部分,编译器会优化它,好像没有泛型(至少在通用接口的这种特殊情况下).

它是否正确?

Chr*_*rau 10

由于编译器有时会添加合成桥接方法,因此可能会出现轻微的性能损失.请考虑以下示例:

public class GenericPerformance {
    public static void main(final String[] args) {
        final Stuff<Integer> stuff = new IntStuff();
        final Integer data = stuff.getData();
        stuff.putData(data);
    }
}

interface Stuff<T> {
    T getData();
    void putData(T stuff);
}

class IntStuff implements Stuff<Integer> {
    private Integer stuff;
    public Integer getData() {
        return stuff;
    }
    public void putData(final Integer stuff) {
        this.stuff = stuff;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果查看生成的字节码,您将看到:在main方法中,擦除了接口方法

java.lang.Object Stuff.getData()
void Stuff.putData(java.lang.Object)
Run Code Online (Sandbox Code Playgroud)

被调用.那些方法,IntStuff用签名实现

java.lang.Object getData()
void putData(java.lang.Object)
Run Code Online (Sandbox Code Playgroud)

两者都使用修饰符public bridge synthetic,委托"真实"方法

java.lang.Integer IntStuff.getData()
void putData(java.lang.Integer)
Run Code Online (Sandbox Code Playgroud)

第一个合成方法只返回Integer结果,而第二个合成方法在调用之前执行从Object到Integer的转换putData(Integer).

如果将stuff变量更改为type IntStuff,Integer则会调用这两个方法而不是合成Object方法.

  • 你是对的.通常,开销是*不值得避免泛型的努力.但似乎JIT无法完全优化桥接方法.我刚刚用一个只包含`final Integer data = intstuff.getData()的循环执行了一些测试; intstuff.putData(数据);`.使用`Stuff <Integer> stuff`变量运行循环比使用`IntStuff stuff`变量需要多30%的时间,即使使用`-server` JVM选项也是如此. (2认同)

the*_*oop 7

Yup - java泛型是一个完全编译时的结构.JVM将其视为普通接口.因此使用泛型没有运行时性能增益或损失.