简体   繁体   English

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

[英]How to call a method on a generic type variable

I'm writing a method that pretty straightforward and easy: I want it to get an object and work on it's starting and ending date. 我正在编写一个非常直接和简单的方法:我希望它能够获得一个对象,然后处理它的开始和结束日期。 All of the object I want it to work on have dates to do stuff with, but of course eclipse won't allow me to write such a method. 我希望它工作的所有对象都有日期来做事,但当然eclipse不允许我编写这样的方法。 Can it be done? 可以吗? How? 怎么样?

Here's the frame I'm working on 这是我正在研究的框架

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

A bit of topic but you could simply remove the genericity and directly use an interface as parameter. 一些主题,但您可以简单地删除通用性并直接使用接口作为参数。

Using OldCurmudgeon interface for the example : 使用OldCurmudgeon接口作为示例:

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

This is not necessary to use generic here and this give a method more verbose and, for non initiate, more obscure. 这不是必须在这里使用泛型,这给了一个更冗长的方法,并且对于非启动,更加模糊。

Generic could be useful if you returned the instance, to chained the method for example. 如果您返回实例,则通用可能很有用,例如链接该方法。 Because with my example, you would need to cast the return instance. 因为在我的示例中,您需要转换返回实例。

You have to tell Java that there is a setStartDate and a setEndDate method in the T objects. 你必须告诉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);
}

Then your objects need to implement this interface. 然后你的对象需要实现这个接口。

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

Incidentally, the way you are working out the end date is dangerous, you are actually modifying the Calendar you are passed as a parameter. 顺便提一下,您计算结束日期的方式很危险,实际上您正在修改作为参数传递的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);

See Defensive copy of Calendar for how to do this right. 有关如何执行此操作,请参阅日历的防御副本 In particular this answer . 特别是这个答案

The objects you want to pass to this method must implement a common interface or extend a common super class that contains the setStartDate() and setEndDate() methods. 要传递给此方法的对象必须实现公共接口或扩展包含setStartDate()setEndDate()方法的公共超类。

Then you can define a type bound on T : 然后你可以在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);
}

where SomeInterface is the common interface. 其中SomeInterface是通用接口。

Your can defined the methods to be exposed by the generic type into an interface: 您可以将泛型类型公开的方法定义到接口中:

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

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

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