在java中使用泛型类型重载构造函数

时间:2014-11-15 21:45:34

标签: java constructor overloading

以下是代码:

import java.util.ArrayList;
import java.util.List;

/**
 * Created by IDEA on 15/11/14.
 */
public class Matrix<T> {
    private final int nrow;
    private final int ncol;

    Matrix(List<List<T>> data) {
        nrow = data.size();
        ncol = data.get(0).size();
    }

    Matrix(List<T[]> data) {
        nrow = data.size();
        ncol = data.get(0).length;
    }
}

IDE要求我删除第一个构造函数,为什么?

2 个答案:

答案 0 :(得分:14)

  

IDE要求我重命名或删除第一个构造函数,为什么?

这是因为泛型在Java中的工作方式。由于类型擦除,你有效地声明了两个这样的构造函数:

Matrix(List data)

这就是JVM看到的内容,其中添加了一些关于所涉及的类型参数的元数据。

这不仅适用于构造函数 - 您也不能基于泛型类型参数重载方法。

有关可怕的详细信息,请参阅Java Generics FAQ entry on type erasure

奇怪的是你的构造函数只需要行数和列数,但这是一个使用静态工厂方法的版本:

import java.util.ArrayList;
import java.util.List;

public class Matrix<T> {
    private final int nrow;
    private final int ncol;

    private Matrix(int nrow, int ncol) {
        this.nrow = nrow;
        this.ncol = ncol;
    }

    public static <T> Matrix<T> fromArrays(List<T[]> data) {
        return new Matrix<T>(data.size(), data.get(0).length);
    }

    public static <T> Matrix<T> fromLists(List<? extends List<T>> data) {
        return new Matrix<T>(data.size(), data.get(0).size());
    }
}

使用它的演示:

public class Test {
    public static void main(String[] args) {
        // We're only checking the compilation for the moment :)
        List<List<String>> lists = null;
        List<String[]> arrays = null;

        Matrix<String> x = Matrix.fromArrays(arrays);
        Matrix<String> y = Matrix.fromLists(lists);
    }
}

答案 1 :(得分:4)

因为两个构造函数具有相同的签名(相同数量的参数和相同的类型)。泛型类型不足以构成重载的构造函数/方法,这是因为类型擦除。

由于类型擦除,两个构造函数都被视为Matrix(List a)