内部函数对实例化对象有什么影响?

时间:2015-01-09 20:34:14

标签: scala guava typetoken

构建

时,以下代码失败
 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>

1 个答案:

答案 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类是通用的。