Простой вопрос, но хитрый ответ я предполагаю.
Использующая Универсальная производительность вреда Интерфейсов?
Пример:
public interface Stuff<T> {
void hello(T var);
}
vs
public interface Stuff {
void hello(Integer var); <---- Integer used just as an example
}
Моя первая мысль - то, что это не делает. Дженерики являются просто частью языка, и компилятор оптимизирует его, как будто не было никаких дженериков (по крайней мере в данном случае универсальных интерфейсов).
Это корректно?
Существует вероятность незначительной потери производительности, поскольку компилятор иногда добавляет синтетические методы моста. Рассмотрим следующий пример:
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;
}
}
Если вы посмотрите на сгенерированный байткод, то увидите: В методе main вызываются методы стертого интерфейса
java.lang.Object Stuff.getData()
void Stuff.putData(java.lang.Object)
-. Эти методы, реализованные в IntStuff
с сигнатурами
java.lang.Object getData()
void putData(java.lang.Object)
обе с модификаторами public bridge synthetic
, делегируют "настоящим" методам
java.lang.Integer IntStuff.getData()
void putData(java.lang.Integer)
Первый синтетический метод просто возвращает результат Integer, а второй выполняет приведение из Object в Integer перед вызовом putData(Integer)
.
Если изменить переменную stuff
на тип IntStuff
, то вместо синтетических Object
методов будут вызваны оба Integer
.
Ага - дженерики java полностью создаются во время компиляции. JVM видит это как обычный интерфейс. Таким образом, при использовании дженериков не происходит увеличения или уменьшения производительности во время выполнения.
Они просто помогают во время компиляции обеспечить безопасность типов.
Обобщения реализуются путем стирания типа: информация об общем типе присутствует только во время компиляции, после чего она стирается компилятором.
Взято из: http://java.sun.com/j2se/1.5.0/docs/guide/language/generics.html
На самом деле, я считаю, что в вашем примере ЕСТЬ небольшая разница в производительности. Скомпилированная форма первой версии предполагает, что hello() получает Object, а во второй - Integer.
Поэтому, когда вы инстанцируете StuffImpl
-- СПРАВКА --
Неявное приведение не будет добавлено к hello(). Однако, если вы добавите метод getter, возвращающий T, приведение будет добавлено к возвращаемому значению.
Итог таков - использование дженериков в некоторых случаях оказывает негативное влияние на производительность по сравнению с недженериковым кодом, ограниченным конкретными типами.