3

Шаблоны в Java

В Java 5 наконец-то появились шаблоны. После C++ без них как-то совсем тяжко :) Эмулировать шаблоны, создавая все структуры данных (т.е. классы) для базового типа object - имхо, идея не очень хорошая.

В-общем, я обрадовался, все хорошо и замечательно, в душе пели птички, в реальности тоже (и при этом прическу и одежду не портили), полная идиллия.
До тех пор, пока мне не приспичило написать (подобно тому, как раньше писал в C++) :

class foo<T>
{
...
T data[] = new T[n];
...
}

Тут меня компилятор долбанул темечком об грешную землю.
Полез в книжки, почитал - и правда, низзя в Java 5 и 6 создавать внутри шаблонного класса объекты типа-параметра. Честно говоря, жалко было, но как-то без создания объектов обошелся, и ничего. Не так давно подумал, что это ограничение все же можно обойти.

Например, можно написать на Java код для шаблона динамического массива. Правда, в конструктор массива придется передать все же ссылку на один инициализированный объект нужного или производного от него класса.
Реализация вот такая:

package examples;
import java.lang.*;
import java.lang.reflect.*;

public class ExampleGen<T1>
{
T1 dim[] = null;
Class cl = null;
//Конструктор. передаем в кач-ве параметра инициализированную ссылку на объект
//нужного (или производного от него) типа
public ExampleGen(T1 var)
{
cl = var.getClass();
}
public void setSize(int n)
{
T1 tmp[] = (T1 [])Array.newInstance(cl, n);
if(dim != null)
for(int i=0; i < dim.length && i < n; i++)
tmp[i] = dim[i];
dim = tmp;
}
public int getSize()
{
return dim.length;
}
public T1 get(int n)
{
return dim[n];
}
public void set(int n, T1 value)
{
dim[n] = value;
}
public T1 [] getArray()
{
T1 tmp[] = (T1 [])Array.newInstance(cl, dim.length);
if(dim != null)
for(int i=0; i < dim.length; i++)
tmp[i] = dim[i];
return tmp;
}
public static void main(String [] args)
{
ExampleGen data;
data = new ExampleGen<T1>( new Double(1.0) );
data.setSize(20);
for(int i=0; i < data.getSize(); i++)
data.set(i, new Double(Math.cos((double)i+1)) );
System.out.println("Values of structure:");
for(int i=0; i < data.getSize(); i++)
System.out.println("Value #" + i + " = " + data.get(i));

Double a[] = data.getArray();
System.out.println("\nValues of array:");
for(int i=0; i < data.getSize(); i++)
System.out.println("Value #" + i + " = " + a[i]);
}
}

Все работает. Инициализированная ссылка нужна лишь для того, что бы получить описание класса - заполнить поле cl.

3 коммент.:

Andrew комментирует...

Идиотизм какой-то. Если у вас встает подобная задача значит у вас ошибка на уровне дизайна приложения.

Lotrex комментирует...

Идиотизм какой-то. Если у вас встает подобная задача, значит у вас ошибка на уровне дизайна приложенияОтчего же идиотизм? Не вижу ничего страшного в более полном использовании возможностей языка. Я не призываю использовать шаблоны для создания soft arrays в Java, как показано в примере.
Но возможность создания экземпляров объектов заведомо неизвестных классов, имхо - весьма мощный инструмент. Так сложилось, что он мне пока не понадобился. Но видимо, понадобится вскоре, раз меня за него ругать стали :)

Анонимный комментирует...

Насколько я понимаю, реализации List-a работают медленнее, чем простой массив []. Если человеку нужна производительность, например, чтобы расчитывать здоровые матрицы, то тут нужен именно массив [], а не реализация List-a.

Отправить комментарий