在下面的代码中,我希望第二种方法也是通用的,但是因为我在方法中创建了Calendar对象,因为type erasure而,我看不出如何。一种可能性是传递Calendar对象,但这会破坏完全使用此方法的主要目的(不必考虑Calendar对象)。
如何让第二种方法适用于多个Calendar的子类,就像第一种方法一样?
public static <U extends Calendar> CalendarMatch<U> tpFromCalendar(U dt)
{
// we want to do all comparisons on UTC calendars
dt.setTimeZone(TimeZone.getTimeZone(DEFAULT_TZ_ID));
return new CalendarMatch<U>(dt);
}
public static CalendarMatch<GregorianCalendar> tpDailyGregorian(int h)
{
GregorianCalendar dt = new GregorianCalendar(TimeZone.getTimeZone(DEFAULT_TZ_ID));
dt.clear();
dt.set(Calendar.HOUR, h);
// this works because of type inference
return tpFromCalendar(dt);
}
答案 0 :(得分:5)
这里绝对没有必要使用反射。所以不要!
public static <U extends Calendar> CalendarMatch<U> tpDailyGregorian(
int h, CalendarFactory<U> factory
) {
Calendar dt = factory.create(TimeZone.getTimeZone(DEFAULT_TZ_ID));
dt.clear();
dt.set(Calendar.HOUR, h);
// this works because of type inference
return tpFromCalendar(dt);
}
其中:
public interface CalendarFactory<U extends Calender {
U create(TimeZone timeZone);
}
答案 1 :(得分:3)
签名可以是:
public static <U extends Calendar> CalendarMatch<U> tpDailyGregorian(int h, Class<? extends U> clazz);
一种方法是使用反射来实例化您的日历(传递Calendar
类型):
Constructor<? extends U> c = clazz.getContructor(TimeZone.class);
U dt = c.newInstance(TimeZone.getTimeZone(DEFAULT_TZ_ID));
当然,使用此dt
个实例,您只能调用Calendar
上的方法而不是GregorianCalendar
dt.clear();
dt.set(Calendar.HOUR, h);
Date d = dt.getGregorianChange(); //CANNOT CALL THIS!