标签: erasure

Gson TypeToken如何运作?

据我所知,在Java中,例如,C#泛型是编译时功能,并通过类型擦除删除.那么,Gson TypeToken的确如何运作?它是如何获得对象的泛型类型的?

java generics gson erasure

21
推荐指数
2
解决办法
2006
查看次数

Scala中泛型类型的模式匹配

我有scala函数,如下所示:

现在,根据T的类型(在我的情况下,它可以是Double,BooleanLocalDate),我需要应用函数ob.像这样的东西(我知道代码没有任何意义,但我想传达我的意思):

def X[T](ob: Observable[T]): Observable[T] = {
    //code  
    T match {
    case Double => DoSomething1(ob:Observable[Double]):Observable[Double]
    case Boolean => DoSomething2(ob:Observable[Boolean]):Observable[Boolean]
    case LocalDate => DoSomething3(ob:Observable[LocalDate]):Observable[LocalDate]
    }
}
Run Code Online (Sandbox Code Playgroud)

考虑到Scala的Erasure属性,可以用某种方式反射来完成工作吗?它甚至可能吗?

generics reflection scala pattern-matching erasure

20
推荐指数
1
解决办法
1万
查看次数

实现Comparable,compareTo名称冲突:"具有相同的擦除,但不会覆盖其他"

我想有一个compareTo方法,它接受一个Real(一个用于处理任意大而精确的实数的类[好吧,只要它的长度小于2 ^ 31])和compareTo方法一个对象,但Java不让我,我没有足够的经验知道为什么.

我只是尝试修改类来实现Comparable,我在下面收到了这些错误消息.我真的不明白错误信息是什么意思,但我知道它与可怕的方式有关,我试图给我们的课程一些灵活性,为我制作的每一种方法提供所有不同的方法签名,我可以修复它通过删除compareTo(Object other)方法,但我最好保留它.所以我真正要问的是:有没有办法让这些错误消息消失而不删除compareTo(Object other)方法,这些错误究竟是什么意思?

另外,我知道已经有一些像BigInteger这样的内置Java类,以及我正在尝试使用这个类的东西,但我正在为了与Project Euler(https://一起使用)的乐趣/满足而这样做projecteuler.net/).

Jake@Jake-PC /cygdrive/c/Users/Jake/Documents/Java/Mathematics
$ javac Real.java
Real.java:377: error: name clash: compareTo(Real) in Real overrides a method whose erasure is the same as another method, yet neither overrides the other
  public int compareTo(Real other)
             ^
  first method:  compareTo(Object) in Real
  second method: compareTo(T) in Comparable
  where T is a type-variable:
    T extends Object declared in interface Comparable
Real.java:440: error: name clash: compareTo(Object) in Real and compareTo(T) in Comparable have the …
Run Code Online (Sandbox Code Playgroud)

java generics overriding comparable erasure

14
推荐指数
1
解决办法
2万
查看次数

Java泛型类型擦除

我想问一下java类型的擦除规则.

如果我们有课程:

public class Shape{}
public class Circle extends Shape{}


public class Base<T extends Shape>{
    T x;
    public void setX(T t){}
}

public class MainClass(){
    public static void main(String... _arg){
         Base<? extends Shape> bs = new Base<Circle>(); 
         bs.setX(new Circle()); // <- compilation problem
    }
}
Run Code Online (Sandbox Code Playgroud)

你能解释一下为什么调用setX()方法会导致编译问题吗?

java generics erasure

11
推荐指数
1
解决办法
536
查看次数

为什么使用原始类型变量会影响签名而不引用类型参数?

在研究另一个问题时,我碰到了1.8.0_112 Sun-Oracle编译器的这种有趣行为(我没有和其他人一起测试过):

import java.util.List;

interface Alpha<T> {
   List<Integer> intList();
}

interface Beta {
   List<Integer> intList();
}

class Main {

   public static void main(String[] args) {

      Alpha rawAlpha = null;
      Alpha<Character> charAlpha = null;
      Alpha<?> qmAlpha = null;
      Beta beta = null;

      for (Integer i : charAlpha.intList()) {}
      for (Integer i : qmAlpha.intList()) {}
      for (Integer i : beta.intList()) {}
      for (Integer i : rawAlpha.intList()) {}
   }
}
Run Code Online (Sandbox Code Playgroud)

编译器在最后一个for循环中失败:

error: incompatible types: Object cannot be converted to …
Run Code Online (Sandbox Code Playgroud)

java generics type-erasure erasure

11
推荐指数
1
解决办法
161
查看次数

Java擦除如何影响通用数组?

我正在研究这一时期的仿制药,今天我已经为我找到了这个谜.

让我们考虑以下虚拟类:

    public class Main{

    public static void main(String[] args) { 
        Container<Integer> c = new Container<Integer>(); 

        c.getArray();                      //No Exception
        //c.getArray().getClass();         //Exception
        //int a = c.getArray().length;     //Exception

    } 

}


class Container<T> { 

    T[] array; 

    @SuppressWarnings("unchecked") 
    Container() { 
        array = (T[])new Object[1]; 
    } 

    void put(T item) { 
        array[0] = item; 
    } 

    T get() { return array[0]; } 

    T[] getArray() { return array; }
}  
Run Code Online (Sandbox Code Playgroud)

由于擦除,在运行时,getArray()方法的T []返回类型变为Object [],这对我来说是完全合理的.

如果我们按原样访问该方法(c.getArray())没有抛出异常,但是如果我们尝试在返回的数组上调用某些方法,例如c.Array().getClass(),或者如果我们尝试访问一个字段,例如c.getArray().length,然后抛出以下异常:

线程"main"中的异常java.lang.ClassCastException:[Ljava.lang.Object; 无法转换为[Ljava.lang.Integer;

为什么抛出此异常?为什么不对简单的c.getArray()调用抛出它?如果我们只是调用getClass()或访问长度,它为什么要尝试强制转换为Integer []?对于[],getClass()和长度是否也不可用?

在此先感谢您的许多(我希望)和解释(我也希望这样)答案.

java arrays generics erasure

10
推荐指数
1
解决办法
153
查看次数

Java和Kotlin使用泛型进行投射.丢失类型安全

在使用Kotlin/Java进行编码时,我在使用强制转换和泛型时偶然发现了一些奇怪的东西.似乎有可能让类型系统认为列表是类型List<Foo>,而它实际上是一个List<Object>.

任何人都可以向我解释为什么这是可能的?

以下是Kotlin和Java中的一个例子:

Kotlin中的例子

fun <T> test(obj: Any): List<T> {
    val ts = ArrayList<T>()
    ts.add(obj as T)
    return ts
}

fun <T> test2(obj: Any): T {
    return obj as T
}

fun <T> test3(obj: Any): List<T> {
    val ts = ArrayList<T>()
    ts.add(test2(obj))
    return ts
}


fun main(args: Array<String>) {
    val x = test<Double>(1) // Returns a list of Integers and doesn't error
    println(x)

    val y = test2<Double>(1) // Casts the Int object to a Double.
    println(y) …
Run Code Online (Sandbox Code Playgroud)

java generics casting kotlin erasure

9
推荐指数
2
解决办法
612
查看次数

清单[T] .erasure在2.10中已弃用,我现在应该使用什么?

我有以下代码:

object Log {

  def get[T](implicit manifest : Manifest[T] ) = {
    LoggerFactory.getLogger( manifest.erasure.getName )
  }

  def getByName( name : String ) = {
    LoggerFactory.getLogger(name)
  }

}
Run Code Online (Sandbox Code Playgroud)

想法是这样使用它:

object SimpleFuture {
  val log = Log.get[SimpleFuture[Throwable,Nothing]]
}
Run Code Online (Sandbox Code Playgroud)

但编译器(2.10)现在表示manifest.erasure已弃用.我现在应该使用什么来实现相同的功能?

generics scala implicit scala-2.10 erasure

8
推荐指数
1
解决办法
2222
查看次数

具有相同擦除的两种方法不一定是覆盖等价的(或者它们之间的签名不是子签名)?

我正在为jdk6阅读令人难以置信的书"java scjp认证的程序员指南",以及关于泛型覆盖的部分.在它上面描述了subsignature和override-equivalent,并描述了一些我引用的覆盖等价的例子:

给定以下三个类中的泛型方法声明:

static <T> void merge (MyStack<T> s1, MyStack<T> s2) { /*...*/ }

static <T> void merge (MyStack<T> s1, MyStack<? extends T> s2) { /*...*/ }

static <T> void merge (MyStack<T> s1, MyStack<? super T> s2) { /*...*/ }

在擦除之后,所有三种方法的签名是:merge(MyStack, MyStack) 即,方法的签名是覆盖等价的,因此这些方法不会过载.

我并不完全同意这些方法是覆盖等价的,事实上我认为这些方法有一个"擦除名称冲突",但没有一个是另一个的子签名...可能我错了所以我想对此有所了解.

子签名的定义让我觉得它们不是它们之间的子签名.

在JSL 6#8.4.2方法签名中(http://docs.oracle.com/javase/specs/jls/se6/html/classes.html#8.4.2)

如果两个方法具有相同的名称和参数类型,则它们具有相同的签名.如果满足以下所有条件,则两个方法或构造函数声明M和N具有相同的参数类型:

  • 他们.具有相同数量的形式参数(可能为零)

  • 它们具有相同数量的类型参数(可能为零)

  • 让我们<A1,...,An>为M的形式类型参数,让<B1,...,Bn>是N的形式类型参数重命名的N的类型艾一碧的每次出现相应类型变量的范围和参数类型M和N都是一样的了.

如果m2与m1具有相同的签名,或者m1的签名与m2的签名擦除相同,则方法m1的签名是方法m2的签名的子签名.

...

如果m1是m2的子签名或m2是m1的子签名,则两个方法签名m1和m2是覆盖等价的.

在JSL 8#8.4.2中.Method Signature(http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.2)

两个方法或构造函数M和N具有相同的签名,如果它们具有相同的名称,相同的类型参数(如果有的话)(第8.4.4节),并且在将形式参数类型N调整为类型参数之后M,相同的形式参数类型.

方法m1的签名是方法m2的签名的子签名,如果:

  • m2与m1具有相同的签名,或

  • m1的签名与m2的签名擦除相同.

如果m1是m2的子签名或m2是m1的子签名,则两个方法签名m1和m2是覆盖等价的.

编辑1

简单来说,我的疑问是,从擦除方面的子签名定义我明白"没有擦除的一个签名等于来自其他签名的擦除"......而不是"擦除后的两个签名是相等的".它的微妙但重要(顺便说一句,覆盖等效定义是基于子签名定义,这就是为什么我用子签名来问)

java generics signature erasure

8
推荐指数
1
解决办法
359
查看次数

实例List和Listof <?>之间的区别

我知道我们不能调用,instanceof List<E>因为List<E>它不是一个可再生的类型.兼顾instanceof Listinstanceof List<?>工作; 然而eclipse IDE建议使用instanceof List<?>.

我想知道为什么它建议使用未绑定的通配符instanceof List<?>而不是原始调用instanceof List.未绑定的通配符是否instanceof List<?>比原始调用有任何优势instanceof List

预先感谢.

编辑1:实际上,instanceof Listinstanceof List<?>编译器在编译时将擦除类型相同.但是化妆品的原因旁边,梅纳指出的,它有其他任何理由使用instanceof List<?>赞成instanceof List

编辑2:根据Oracle的这个条目:

  1. instanceof/cast表达式的类型是raw

这种情况经常发生,因为javac禁止其目标类型为泛型类型的instanceof表达式; 对于强制类型转换,编译器稍微宽松一些,因为允许转换为泛型类型,但会发出警告(参见上文).无论如何,原始类型应该由无界通配符替换,因为它们具有类似的属性和子类型.

Object o = new ArrayList<String>(); List<?> list_string = (List)o; //same as (List<?>)o boolean b = o instanceof List; //same as o instanceof List<?>

因此,我们可以推断,除了Mena所说的美容理由和使用genenics的限制,instanceof List并且instanceof …

java generics collections type-erasure erasure

8
推荐指数
1
解决办法
600
查看次数