Java 如何对泛型类型变量调用方法

Java 如何对泛型类型变量调用方法,java,date,generics,Java,Date,Generics,我正在写一个非常简单明了的方法: 我想让它得到一个对象,并确定它的开始和结束日期。 我希望它处理的所有对象都有日期,但eclipse当然不允许我编写这样的方法。 能做到吗?怎么做 这是我正在制作的框架 public <T> void updateStuff(T stuffObject, Calendar startDate, Integer delta) { stuffObject.setStartDate(startDate); Calendar calendarE

我正在写一个非常简单明了的方法: 我想让它得到一个对象,并确定它的开始和结束日期。 我希望它处理的所有对象都有日期,但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);
}
public void updateStuff(T stuff对象、日历开始日期、整数增量){
stuffObject.setStartDate(startDate);
Calendar calendarEnd=Calendar.getInstance();
日历结束=开始日期;
calendarEnd.add(Calendar.MONTH,增量);
stuffObject.setEndDate(calendarEnd);
}

要传递到此方法的对象必须实现一个公共接口或扩展一个包含
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);
}
public void updateStuff(T stuff对象、日历开始日期、整数增量){
stuffObject.setStartDate(startDate);
Calendar calendarEnd=Calendar.getInstance();
日历结束=开始日期;
calendarEnd.add(Calendar.MONTH,增量);
stuffObject.setEndDate(calendarEnd);
}

其中,
SomeInterface
是公共接口。

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

    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);
    }
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;
    }
}
public void updateStuff(T stuff对象、日历开始日期、整数增量){
stuffObject.setStartDate(startDate);
Calendar calendarEnd=Calendar.getInstance();
日历结束=开始日期;
calendarEnd.add(Calendar.MONTH,增量);
stuffObject.setEndDate(calendarEnd);
}
接口MyInterface{
无效设置开始日期(日历c);
作废setEndDate(日历c);
}

您必须告诉Java在
T
对象中有一个
setStartDate
和一个
setEndDate
方法

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);
}
顺便说一句,计算结束日期的方式很危险,实际上是在修改作为参数传递的
日历

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

请参阅,了解如何正确执行此操作。特别是。

有点像主题,但您可以简单地删除泛型,直接使用接口作为参数

例如:

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);
}
这里不需要使用泛型,这会使方法更加详细,对于非初始化方法,会更加模糊


如果返回实例(例如链接方法),则泛型可能很有用。因为在我的示例中,您需要强制转换返回实例。

基本上意味着
T
将继承
对象,但仅此而已。您需要使用
至少确保泛型类型是
SomeClass
中的一个,然后能够使用
stuffObject.methodOfSomeClass
您需要扩展T,否则您不能对它做很多事情。如果您使用的是JDK 8+,您会如何使用
TemporalAccessor
接口?(例如,
T extensed TemporalAccessor
)顺便说一句,我们可以简单地执行
public void updateStuff(SomeInterface stuff object,Calendar startDate,Integer delta)
。因为没有返回任何内容,所以对使用泛型没有真正的兴趣type@AxelH同意-需要检查在这种情况下使用泛型类型的理由。您可能可以在该特定示例中确认我的想法。这不是太过分了吗?使用接口作为参数类型就足够了,如果返回了
T
,它会很有用,但在这里,我认为不需要泛型性。@AxelH这是一个很好的观点。我的答案包括泛型,因为问题包括泛型,但我同意在这个特定示例中,您可以不使用泛型。别误会,我指的是原始问题中的问题,而不是您的答案;)我喜欢的答案。没有必要把事情进一步复杂化。