I am trying to write a method in which I need to create a temp variable, sum, of generic type T. However, I'm getting the error "The local variable sum may not have been initialized". How can I initialize a generic variable? I can't set it to 0 or 0.0, and I can't find information anywhere on how to deal with this. Here is the portion of code that I'm working with:
public Matrix<T,A> multiply(Matrix<T,A> right) throws MatrixException
{
Matrix<T,A> temp = new Matrix<T,A>(arithmetics, rowSize, columnSize);
T sum, product;
if (rowSize != right.columnSize)
throw new MatrixException("Row size of first matrix must match column size "
+ "of second matrix to multiply");
setup(temp,rowSize,columnSize);
for (int i = 0; i < rowSize; i++){
for (int j = 0; j < right.columnSize; j++) {
product = (arithmetics.multiply(matrix[i][j] , right.matrix[j][i]));
sum = arithmetics.add(product, sum);
temp.matrix[i][j] = sum;
}
}
return temp;
}
I'm not sure if this will help clarify, but here is my interface Arithmetics:
public interface Arithmetics<T> {
public T zero();
public T add( T a, T b );
public T subtract( T a, T b);
public T multiply (T a, T b);
public T parseString( String str );
public String toString( T a );
}
And here is one of my classes, DoubleArithmetics, just to show how I'm implementing the interface:
public class DoubleArithmetics implements Arithmetics<Double> {
protected Double value;
public Double zero()
{
return new Double(0);
}
public Double add( Double a, Double b )
{
return new Double(a.doubleValue()+b.doubleValue());
}
public Double subtract (Double a, Double b)
{
return new Double(a.doubleValue()-b.doubleValue());
}
public Double multiply (Double a, Double b)
{
return new Double(a.doubleValue()*b.doubleValue());
}
public Double parseString( String str )
{
return Double.parseDouble(str);
}
public String toString( Double a )
{
return a.toString();
}
}
It specifies the type parameters (also called type variables) T1, T2, ..., and Tn. To update the Box class to use generics, you create a generic type declaration by changing the code "public class Box" to "public class Box<T>". This introduces the type variable, T, that can be used anywhere inside the class.
If you want to initialize Generic object, you need to pass Class<T> object to Java which helps Java to create generic object at runtime by using Java Reflection.
Creating a simple generic type is straightforward. First, declare your type variables by enclosing a comma-separated list of their names within angle brackets after the name of the class or interface. You can use those type variables anywhere a type is required in any instance fields or methods of the class.
A generic type is like a template. You cannot create instances of it unless you specify real types for its generic type parameters. To do this at run time, using reflection, requires the MakeGenericType method.
Just use the zero
method that you already have on your interface to initialize sum
:
T sum = arithmetics.zero();
For the non-zero initialization, you could also add methods that take long
and double
values and return the T
for them:
public interface Arithmetics<T> {
public T zero();
public T create(long l);
public T create(double d);
public T add( T a, T b );
public T subtract( T a, T b);
public T multiply (T a, T b);
public T parseString( String str );
public String toString( T a );
}
And then implement them:
public Double create(long l) {
return new Double(l);
}
public Double create(double d) {
return new Double(d);
}
And finally, to use them:
T one = arithmetics.create(1);
Instantiating generics in Java is a bit tricky due to type erasure.
My approach is to pass into your generic class' constructor two items: (1) a java.lang.reflect.Constructor specific to type T; and (2) an Object[] array holding a default value specific to type T.
When you later want to instantiate and initialize a type T, you need to call Constructor.newInstance(Object[]). In the code below, the MyGenericClass class stands in for your generic class (looks like it's called Matrix from your original post).
I got the solution from InstantiationException for newInstance() and Create instance of generic type in Java?
public class MyGenericClass<T>
{
Constructor _constructorForT;
Object[] _initialValueForT;
public MyGenericClass(Constructor constructorForT,
Object[] initialValueForT)
{
_constructorForT = constructorForT;
_initialValueForT = initialValueForT;
}
public void doSomething()
{
T sum = initializeT(_constructorForT, _initialValueForT);
System.out.printf("d = %f\n", sum);
}
@SuppressWarnings("unchecked")
private T initializeT(Constructor constructor, Object[] args)
{
T result = null;
try
{
result = (T) constructor.newInstance(args);
}
catch (java.lang.InstantiationException ex)
{
}
catch (java.lang.IllegalAccessException ex)
{
}
catch (java.lang.reflect.InvocationTargetException ex)
{
}
return result;
}
public static void main(String argv[]) throws Exception
{
Constructor constructor =
Double.class.getConstructor(new Class[]{double.class});
Object[] initialValue = new Object[] { new Double(42.0) };
MyGenericClass<Double> myGenericClass =
new MyGenericClass<Double>(constructor, initialValue);
myGenericClass.doSomething();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With