如何将自定义 BigDecimal 转换器设置为 TextField在检票口 1.5 中?
从 1.4 到 1.5,除了 之外,似乎还有许多未记录的更改记录在案的。
在 1.4 中,我有:
new TextField<BigDecimal>("capitalInput",
new PropertyModel<BigDecimal>(model, "capital")) {
@Override
public IConverter getConverter(Class<?> type) {
return new MonetaryBigDecimalConverter();
}
};
在 1.5 中,我像这样更改了它(以匹配 getConverter() 现已声明):
new TextField<BigDecimal>("capital",
new PropertyModel<BigDecimal>(model, "capital")) {
@Override
public <C> IConverter<C> getConverter(Class<C> type) {
return new MonetaryBigDecimalConverter();
}
};
我的 IDE 显示为未经检查的赋值警告。但随后尝试构建项目实际上是一个编译错误:
incompatible types
found : com.company.MonetaryBigDecimalConverter
required: org.apache.wicket.util.convert.IConverter<C>
自定义 MonetaryBigDecimalConverter 看起来像这样 (1.5):
public class MonetaryBigDecimalConverter extends BigDecimalConverter {
@Override
public String convertToString(BigDecimal value, Locale locale) {
// ...
}
}
我怎样才能再次使其工作?
Going from 1.4 to 1.5, there seem to be many undocumented changes in addition to the documented ones.
In 1.4 I had:
new TextField<BigDecimal>("capitalInput",
new PropertyModel<BigDecimal>(model, "capital")) {
@Override
public IConverter getConverter(Class<?> type) {
return new MonetaryBigDecimalConverter();
}
};
With 1.5, I changed that like so (to match how getConverter() is now declared):
new TextField<BigDecimal>("capital",
new PropertyModel<BigDecimal>(model, "capital")) {
@Override
public <C> IConverter<C> getConverter(Class<C> type) {
return new MonetaryBigDecimalConverter();
}
};
Which my IDE shows as just unchecked assignment warning. But then trying to build the project it's actually a compilation error:
incompatible types
found : com.company.MonetaryBigDecimalConverter
required: org.apache.wicket.util.convert.IConverter<C>
The custom MonetaryBigDecimalConverter looks something like this (1.5):
public class MonetaryBigDecimalConverter extends BigDecimalConverter {
@Override
public String convertToString(BigDecimal value, Locale locale) {
// ...
}
}
How can I make this work again?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
由于 Wicket 1.5 转换器具有通用类型参数:
请注意,#getConverter() 的类型参数 C 未绑定到文本字段的类型参数,因此您应该测试请求的类型:
您必须将转换器显式转换为请求的 类型IConverter 使编译器安静。或者通过您的解决方法,您将陷入原始类型,从而回避问题。
Since Wicket 1.5 converter has a generic type parameter:
Note that the type argument C of #getConverter() is not bound to the type parameter of your textfield, so you should test the requested type:
You have to explicitely cast your converter to the requested IConverter to quiet the compiler. Or with your workaround you're dropping into a raw type, thus sidestepping the problem.
我不知道为什么,但 getConverter 方法中的以下小更改使其可以编译。
我刚刚将 MonetaryBigDecimalConverter 实例提取到
IConverter
类型的变量中。字段或常数的工作方式类似。 (注意:类型不能是IConverter
或IConverter
。)此代码仍会产生“未经检查的赋值”警告,但至少它可以编译。如果有人添加解释或更好的解决方案,我将不胜感激。对于 Java 泛型的奇怪现象,我当然不是专家。
I have no idea why, but the following small change in getConverter method made it compile.
I just extracted the MonetaryBigDecimalConverter instance into a varible of type
IConverter
. A field or constant would work similarly. (NB: the type must not beIConverter<C>
orIConverter<BigDecimal>
.) This code still produces "unchecked assignment" warning, but at least it compiles.I'd be grateful if someone added an explanation or a better solution altogether. I am certainly no expert when it comes to Java generics oddities.
由于返回值是从运行时传递给方法的任何参数派生的,因此 Java 无法确定返回类型,并且始终需要强制转换。
另一方面,如果返回类型在编译时已知,那么您将能够使用更智能的方法。 (例如,当 Component 是确定
C
类型的泛型类型时,而不是传递给它的参数):因为编译器现在知道
getConverter
> 方法将返回IConverter
,不需要转换。您自己的变量提取解决方案的工作方式与转换为原始类型 IConverter 相同,这也是可能的。无需提取它。
当转换为原始类型时,不是说“我返回 BigDecimal 类型的转换器”(当传递的参数是另一种类型时,这可能是错误的),而是说“我返回任何类型的 IConverter”(这可以用于Java 1.5 中引入泛型时的向后兼容性原因,但当然可以抛出
RuntimeException
)Because the return value is derived from whatever argument is passed to the method at runtime, Java is unable to determine the return type and a cast is always required.
On the other hand, if the return type would have been known upon compilation, then you would have been able to use a more smart approach. (E.g. when Component would have been a generic type that determined the type of
C
, instead of the parameter passed to it) :Because the compiler now knows for a fact that the
getConverter
method will returnIConverter<BigDecimal>
, casting is not required.Your own solution of extracting in a variable works the same as casting to raw type
IConverter
which is also possible. No need extracting it.When casting to raw type, instead of saying 'I return a Converter of type BigDecimal' (which can be wrong when the passed argument is of another type) you are now saying 'I return an IConverter of whatever' (which is made possible for backward compatibility reasons when generics where introduced in Java 1.5, but of-course can throw a
RuntimeException
)