繁体   English   中英

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

[英]Is there any way with which I can avoid type casting while calling method with generic parameter?

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。 可以在调用这些方法时避免类型转换吗?

如果要使方法通用,则需要强制类型转换。 但是,您可以只重载setValue方法。 像这样:

public static void main(String[] args) {

    GenericTest genericTest = new GenericTest();

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

}

public void setValue(BigDecimal element) {
    checkBigDecimal(element);
}

public void setValue(Date element) {
    checkDate(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");
}

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

希望这可以帮助。

问题在于该类没有可在方法调用之间获知的参数类型。 您可以参数化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方法内部,作为验证的一部分。

您可以使事情变得更干净:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM