在使用泛型参数调用方法时,有什么方法可以避免类型转换?

时间:2016-02-16 09:19:03

标签: java generics casting

public static void main(String[] args) {

    GenericTest genericTest = new GenericTest();

    genericTest.setValue(new BigDecimal("10"),BigDecimal.class);
    genericTest.setValue(new Date(0), Date.class);

    }

    public <T> void setValue(T element, Class<T> dataType)
    {
        if(dataType == Date.class){
            checkDate((Date)element);
        }
        else if(dataType == BigDecimal.class){
            checkBigDecimal((BigDecimal)element);
        }
    }

    public void checkDate(Date localDate)
    {
        System.out.println("This is Date metho, Caller has casted T to Date");
    }

    public void checkBigDecimal(BigDecimal localBigDecimal)
    {
        System.out.println("This is BigDecimal method, Caller has casted T to BigDecimal");

    }

这里调用checkDate和CheckBigDecimal方法时,我分别对Date和BigDecimal进行了类型转换。调用这些方法时是否可以避免类型转换?

4 个答案:

答案 0 :(得分:2)

如果您希望方法是通用的,则需要强制转换。但是,您可以改为重载setValue方法。像这样:

{{1}}

答案 1 :(得分:1)

解决问题的一种方法是使用Factory Pattern,专门为需要创建对象的情况创建,而不必为创建的对象指定确切的类。

希望这有帮助。

答案 2 :(得分:1)

问题是该类没有可以跨方法调用知道的参数类型。您可以参数化GenericTest类:

public class GenericTest<T> {
    private T value;

    public void setValue(T value) {
        this.value = value;
    }

    public T getValue() {
        return this.value;
    }
}

最好让参数类型在类范围内绑定,因为依赖于类型的跨方法调用是相同的。换句话说,不要在同一个实例上调用setValue(String)和setValue(Date)。上面的代码应该阻止这样的调用。

通过上述内容,您的类甚至不需要checkDate / checkBigDecimal方法(假设它们用于验证):

GenericTest<Date> dateGeneric = new GenericTest<>();
dateGeneric.setValue(new Date()); //The compiler will prevent any other type to be passed to this method

如果仍然需要checkXYZ方法(例如,您正在验证通用输入),则无法避免转换,因此使用泛型是不合适的。您可以简单地使用Object字段并在checkXYZ方法中强制转换为验证的一部分。

答案 3 :(得分:1)

你可以让事情变得更清洁:

public class genericTest {
    public static void main(String[] args) {
        genericTest genericTest = new genericTest();
        genericTest.setValue(new BigDecimal("10".toString()));
        genericTest.setValue(new Date(0));

    }

    public <T> void setValue(T element) {
        if (element instanceof Date) {
            check((Date) element);
        }

        if (element instanceof BigDecimal) {
            check((BigDecimal) element);
        }
    }

    public void check(Date localDate) {
        System.out.println("This is Date metho, Caller has casted T to Date " + localDate);
    }

    public void check(BigDecimal localBigDecimal) {
        System.out.println("This is BigDecimal method, Caller has casted T to BigDecimal: " + localBigDecimal);
    }
}

然而,这仍然无法解决您的问题,因为仍然需要演员表。问题是您希望在运行时动态应用方法重载。 Java不会这样做 - 编译器将尝试将您的代码解析为特定(重载)方法调用,并且类似下面的内容将失败,因为它不能 找出要应用的check()(如果有的话)

public <T> void setValue(T element) {
    check(element);
}