构建
时,以下代码失败 new TypeParameter[K]() {}
只有mapToken的位置不同。
package net.ailive;
import org.junit.Test;
import com.google.common.reflect.TypeParameter;
import com.google.common.reflect.TypeToken;
import java.math.BigInteger;
import java.util.Map;
import java.util.Queue;
class SampleJUnitScala {
// Succeeds if defined here ***
// def mapToken[K, V](keyToken: TypeToken[K], valueToken: TypeToken[V]): TypeToken[Map[K, V]] = {
// return new TypeToken[Map[K, V]]() {}
// .where(new TypeParameter[K]() {}, keyToken)
// .where(new TypeParameter[V]() {}, valueToken);
// }
@Test
def myTest() = {
// Fails if defined here ***
def mapToken[K, V](keyToken: TypeToken[K], valueToken: TypeToken[V]): TypeToken[Map[K, V]] = {
return new TypeToken[Map[K, V]]() {}
.where(new TypeParameter[K]() {}, keyToken)
.where(new TypeParameter[V]() {}, valueToken);
}
val mapTok = mapToken(
TypeToken.of(classOf[String]),
TypeToken.of(classOf[BigInteger]));
val complexToken = mapToken(
TypeToken.of(classOf[Integer]),
new TypeToken[Queue[String]]() {});
}
}
(TypeParameter.capture()返回null)。
如果我改变了mapToken函数的位置。有用。为什么呢?
在Scala中看到:2.10
TypeToken来自:(?)
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
答案 0 :(得分:1)
字节码中存在一些相当小的差异。向mapToken添加了private final
,将mapToken重命名为mapToken$1
并更改了方法的顺序。还有一个测试通过,一个没有。我能看到的字节码(类名除外)的唯一区别是通用参数:https://public.v6ak.com/scala-inner-vs-outer-function.png
在查看内部类(例如SampleJUnitScalaOuterFunction$$anon$1
)时,除名称外,它们看起来相同。
JVM不使用泛型参数,它们在编译时使用,也由Guava使用。 TypeParameter<T>
的构造函数尝试读取其类型参数T
。
但是,我不确定,为什么mapToken
在外部函数中使用时有效。类型参数未在运行时传递,并且Guava应该无法从new TypeParameter[K]()
读取实际类型,因为SampleJUnitScalaOuterFunction$$anon$3
类是通用的。