下面的代码来自一个名为ButterKnife的Android库。我正在弄清楚它是怎么工作的。
@SuppressWarnings("unchecked") // That's the point.
public <T> T castParam(Object value, String from, int fromPosition, String to, int toPosition) {
try {
return (T) value;
} catch (ClassCastException e) {
throw new IllegalStateException("Parameter #"
+ (fromPosition + 1)
+ " of method '"
+ from
+ "' was of the wrong type for parameter #"
+ (toPosition + 1)
+ " of method '"
+ to
+ "'. See cause for more info.", e);
}
}
我试图重新创建此函数的行为:
@SuppressWarnings("unchecked")
public static <T> T cast(Object o){
try {
return (T) o;
} catch (ClassCastException e){
throw new AssertionError("Error");
}
}
和用法:
Object o = new String("test");
Double d = cast(o);
但是异常并非永远不会被捕获,而是在调用方法时在行中抛出。为什么?
还有,这到底是如何工作的?该方法如何知道要转换到什么?
正如SJuan67所解释的,您不能像Java编译器那样对泛型类型使用强制转换
如果类型参数是无界的,则用其边界或对象替换泛型类型中的所有类型参数。因此,生成的字节码仅包含普通类、接口和方法。
这里有更多关于所有泛型限制的信息。
所以ButterKnife代码看起来像这样:
public Object castParam(Object paramObject, String paramString1, int paramInt1, String paramString2, int paramInt2)
{
return paramObject;
}
因此,对于您的问题:
问:但是异常并不是永远不会被捕获,它会在调用方法时被抛出。为什么?
答:嗯,它甚至不在字节码中。
问:还有,这到底是怎么工作的?方法如何知道要转换成什么?
A: 没有。至少不像你想的那样。在实践中,它将抛出ClassCastException而不是您观察到的非法状态异常或断言错误。您甚至可以使用ButterKnife示例应用程序尝试,并将已知的TextView绑定到复选框:
@Bind(R.id.title) CheckBox title;
问:那么图书馆是如何工作的呢?
答:好吧,IllegalStateException只是从未调用过,而且您有ClassCastException。为什么会这样,我不太确定。但是,当ButterKnife生成代码时,这可能是为了防止编译错误。
例如:
public interface Some {
}
public static void weWantSome(Some d) {
}
public static void test() {
String o = "test";
weWantSome((Some)o); //<-- compile error
weWantSome(Main.<Some>cast(o)); //<-- runtime error
}
这就是为什么在前面的示例中,代码会编译但不会运行。
由于类型擦除,泛型类型仅在编译时检查。这样做是因为在Java5中没有办法在运行时引入泛型,而不会破坏向后兼容性并强制重新编译所有已经存在的库。
长历史短,当您定义“泛型”类或方法时,实际代码将编译为<code>对象</code>而不是绑定方法的类型。所有类型检查都在编译时完成。
因此,您的方法代码实际上并没有在<code>return)分配给<code>对象
我在我的Java程序中写了这个函数: 这就是我所说的: 它是有效的,但我觉得我应该能够省略第一个参数,并从返回类型(结果被分配到的类型)推断出它。这可能吗?如果是,语法是什么?
问题内容: 背景 我曾经写过这种方法: 应该这样称呼它: 这很好用(尽管我在研究当前容易出错的问题时在这里的答案中已经看到)。 目前的情况 无论如何,现在我正在编写以下代码(在扩展javax.servlet.jsp.tagext.TagSupport的类中): 目的是可以这样称呼: 我的评估方法中的代码显然不起作用。的第二个参数应该是Class对象。这导致我: 我的问题 如何获得通用(返回)类型的
我试图创建一个Java方法,它接受一个对象类型和它应该转换成的数据类型。 例如,如果我应该能够返回一个值1作为Int或双根据需要。我使用类传递数据类型作为参数。 问题:如何使方法泛型以接受基于输入参数的返回类型? 下面的代码只是一个示例,它可能在语法上不正确,用于解释我的问题。
我想让一个函数返回一个保证实现两个接口的对象。编译时不一定知道确切的对象。我的代码看起来像: 在尝试编译时,我遇到以下错误: 你好世界java:13:错误:不兼容的类型:C无法转换为T 返回新的C() ^ 其中T是一个类型变量: T扩展了方法f(布尔值) HelloWorld中声明的a,B。java:14:错误:不兼容的类型:D无法转换为T 返回新的D() ^ 其中T是一个类型变量: T扩展了方法
对于一堆带有泛型的包装类,我的继承结构遇到了一些麻烦。这基本上是结构: 这将与当前代码一起编译和工作,但是,这似乎很危险。如果调用方像这样使用这个方法:,它将很好地编译,但是如果findMiddle尝试返回SubBWrapper,则在运行时会有一个ClassCastException。我以为行得通却行不通的是: 所以我的问题基本上是,有没有正确的方法来编写编译、运行并遵循最佳实践的方法findMi
Java中是否有一种方法可以通过一个方法的声明返回不同的类型? 我希望此方法返回一个对象,并在函数调用时将其转换为正确的类型。这就是我的想法,但它不是这样工作的。我是否需要某种通用返回类型来执行此操作?解决这个问题的最佳方法是什么?