如何在Java中初始化一个通用变量?

6

我正在尝试编写一个方法,在这个方法中,我需要创建一个泛型类型T的临时变量sum。然而,我遇到了错误“局部变量sum可能未被初始化”。如何初始化泛型变量?我不能将其设置为0或0.0,并且我找不到任何关于如何处理这个问题的信息。这是我正在使用的代码片段:

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;
}

我不确定这是否能帮助澄清,但这是我的接口算术:

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

}

这里是我的一个类DoubleArithmetics,只是为了展示我如何实现接口:

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

你尝试将其初始化为null了吗? - Wand Maker
如果上面的空值无法使用,那么可以创建一个静态方法:T sum = Arithmetics.initialize();。您可以从该方法返回一个Double。 - Tony Ennis
@WandMaker,我成功地将其初始化为null。我不知道我怎么会忽略了这个!谢谢你。 - woollyMammoth
很酷,我把它作为答案发布了。Brian的另一个答案看起来更优雅。 - Wand Maker
实际上,@WandMaker,当我初始化为null时,会抛出NullPointerException异常。似乎是在调用add()方法并将sum设置为null时抛出了异常。你知道如何避免这个问题吗? - woollyMammoth
你必须先创建一个类型为T的实例。 - stackoverflowuser2010
2个回答

3

只需在您的接口上使用zero方法来初始化sum

T sum = arithmetics.zero();

对于非零初始化,您也可以添加使用longdouble值作为参数并返回它们的T类型的方法:

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

然后实现它们:

public Double create(long l) {
    return new Double(l);
}

public Double create(double d) {
    return new Double(d);
}

最后,使用它们的方法如下:
T one = arithmetics.create(1);

通过这种方式使用方法(即返回特定类型而不是通用类型),您正在破坏通用容器的整个目的。create() 方法应该返回类型 T。Arithmetics<T> 的实现也应该有一个返回类型 T 的 create() 方法。 - stackoverflowuser2010
1
@stackoverflowuser2010 你在说什么?我的方法明显返回 T,它们都是 public T create - Brian
接口的create()方法返回T。实现的方法也应该返回T。在你的代码中,你的实现的create()方法返回Double。 - stackoverflowuser2010
1
因为他的示例中有 implements Arithmetic<Double> 的实现,所以我展示了一个与他相符的示例实现。 - Brian

3
在Java中实例化泛型有些棘手,这是由于类型擦除造成的。我的方法是将两个项目传递到泛型类构造函数中:(1)一个特定于类型T的java.lang.reflect.Constructor;和(2)一个包含特定于类型T的默认值的Object[]数组。
当您稍后想要实例化和初始化类型T时,需要调用Constructor.newInstance(Object[])。在下面的代码中,MyGenericClass类代表您的泛型类(从您的原始帖子中看起来它被称为Matrix)。
我从InstantiationException for newInstance()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();

    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接