Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I initialize a generic variable in Java?

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();
}
}
like image 516
woollyMammoth Avatar asked Jun 30 '13 18:06

woollyMammoth


People also ask

How do you declare a generic variable in Java?

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.

How do you initialize a generic object in Java?

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.

How do you declare a generic variable?

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.

Can you instantiate a generic type?

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.


2 Answers

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);
like image 117
Brian Avatar answered Oct 04 '22 21:10

Brian


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();

    }
}
like image 27
stackoverflowuser2010 Avatar answered Oct 04 '22 21:10

stackoverflowuser2010