如何在泛型类型变量上调用方法

时间:2017-10-19 08:35:34

标签: java date generics

我正在编写一种非常简单易用的方法: 我希望它能得到一个对象并开始它的开始和结束日期。 我希望它工作的所有对象都有日期来做事,但当然eclipse不允许我编写这样的方法。 可以吗?怎么样?

这是我正在研究的框架

public <T> void updateStuff(T stuffObject, Calendar startDate, Integer delta) {
    stuffObject.setStartDate(startDate);
    Calendar calendarEnd = Calendar.getInstance();
    calendarEnd = startDate;
    calendarEnd.add(Calendar.MONTH, delta);
    stuffObject.setEndDate(calendarEnd);
}

4 个答案:

答案 0 :(得分:3)

有点主题,但您可以简单地删除通用性并直接使用接口作为参数。

使用OldCurmudgeon interface作为示例:

interface Stuff {
    void setStartDate(Calendar startDate);
    void setEndDate(Calendar startDate);
}

public void updateStuff(Stuff stuffObject, Calendar startDate, Integer delta) {
    stuffObject.setStartDate(startDate);
    Calendar calendarEnd = Calendar.getInstance();
    calendarEnd = startDate;
    calendarEnd.add(Calendar.MONTH, delta);
    stuffObject.setEndDate(calendarEnd);
}

这不是必须在这里使用泛型,这给了一个更详细的方法,并且对于非启动,更加模糊。

如果您返回实例,通用可能很有用,例如链接该方法。因为在我的示例中,您需要转换返回实例。

答案 1 :(得分:2)

您必须告诉Java setStartDate个对象中有setEndDateT方法。

interface Stuff {
    void setStartDate(Calendar startDate);
    void setEndDate(Calendar startDate);
}

public <T extends Stuff> void updateStuff(T stuffObject, Calendar startDate, Integer delta) {
    stuffObject.setStartDate(startDate);
    Calendar calendarEnd = Calendar.getInstance();
    calendarEnd = startDate;
    calendarEnd.add(Calendar.MONTH, delta);
    stuffObject.setEndDate(calendarEnd);
}

然后您的对象需要实现此接口。

class SomeStuff implements Stuff {
    Calendar startDate;
    Calendar endDate;

    @Override
    public void setStartDate(Calendar startDate) {
        this.startDate = startDate;
    }

    @Override
    public void setEndDate(Calendar startDate) {
        this.endDate = endDate;
    }
}

顺便提一下,您计算结束日期的方式很危险,实际上您正在修改作为参数传递的Calendar

    Calendar calendarEnd = Calendar.getInstance();
    // Throw away the new Calendar and point calendarEnd at the parameter.
    calendarEnd = startDate;
    // change the parameter.
    calendarEnd.add(Calendar.MONTH, delta);

请参阅Defensive copy of Calendar了解如何正确执行此操作。特别是this answer

答案 2 :(得分:1)

要传递给此方法的对象必须实现公共接口或扩展包含setStartDate()setEndDate()方法的公共超类。

然后,您可以定义T上绑定的类型:

public <T extends SomeInterface> void updateStuff(T stuffObject, Calendar startDate, Integer delta) {
    stuffObject.setStartDate(startDate);
    Calendar calendarEnd = Calendar.getInstance();
    calendarEnd = startDate;
    calendarEnd.add(Calendar.MONTH, delta);
    stuffObject.setEndDate(calendarEnd);
}

其中SomeInterface是公共接口。

答案 3 :(得分:1)

您可以将泛型类型公开的方法定义到接口中:

    public <T extends MyInterface> void updateStuff(T stuffObject, Calendar startDate, Integer delta) {
        stuffObject.setStartDate(startDate);
        Calendar calendarEnd = Calendar.getInstance();
        calendarEnd = startDate;
        calendarEnd.add(Calendar.MONTH, delta);
        stuffObject.setEndDate(calendarEnd);
    }

    interface MyInterface{
        void setStartDate(Calendar c);
        void setEndDate(Calendar c);
    }