简体   繁体   English

Eclipse自动完成 - 当只有二进制jar可用时,它如何知道泛型?

[英]Eclipse autocompletion - how does it know about generics when only binary jar is available?

Java generics are implemented using type erasure. 使用类型擦除实现Java泛型。 That means that if I have a method: 这意味着如果我有一个方法:

public void setMapParam(Map<String, Integer> p) { ... }

after compilation, it will end up in the .class as: 在编译之后,它将最终在.class中:

public void setMapParam(Map p) { ... }

I have a JAR file with generic classes and methods like the above. 我有一个JAR文件,其中包含如上所述的泛型类和方法。 It is just the binary. 它只是二进制文件。 No source code no nothing. 没有源代码也没有。

But when I use it in code, Eclipse auto completion gives me setMapParam(Map<String, Integer> p) even though in the binary is like setMapParam(Map p) . 但是当我在代码中使用它时,Eclipse自动完成给了我setMapParam(Map<String, Integer> p)即使在二进制文件中就像setMapParam(Map p)

How does Eclipse now the type ( Map<String, Integer> ) even if the method signature has been type erased (to Map )? 即使方法签名已被类型擦除(到MapMap<String, Integer> Eclipse现在如何处理类型( Map<String, Integer> )? Or am I missing something? 或者我错过了什么?

Type erasure does not mean that the compiled code contains no type parameter information. 类型擦除并不意味着编译后的代码不包含任何类型的参数信息。 Type parameters that are used in class and member definitions are present in the compiled code and available via reflection (see TypeVariable ). 类和成员定义中使用的类型参数存在于已编译的代码中,并可通过反射获得(请参阅TypeVariable )。

What type erasure means is that object instances do not have individual type parameters. 什么类型的擦除意味着对象实例没有单独的类型参数。 Given a class definition MapImpl extends HashMap<T extends Comparable, Integer> and an instance of that class, you cannot find out what specific value of T was used in the code that created the instance, because that information does not exist. 给定一个类定义MapImpl extends HashMap<T extends Comparable, Integer>和该类的实例,您无法找出在创建该实例的代码中使用了什么特定的T值,因为该信息不存在。 But you can find out that it extends Comparable and that the value type is Integer , because that information is part of the class definition (and shared by all instances). 但是你可以发现它extends Comparable并且值类型是Integer ,因为该信息是类定义的一部分(并由所有实例共享)。

No, parameters retain their generic type information. 不,参数保留其通用类型信息。

Type erasure is about an instance of List<T> not knowing what T is at execution time, for example. 例如,类型擦除是关于List<T>的实例,不知道T在执行时是什么。 There's only really a List class - the rest is up to the compiler. 实际上只有一个List类 - 其余的由编译器决定。 But the compiler can use information about parameter types, and the type itself. 但编译器可以使用有关参数类型和类型本身的信息。

Here's an example: 这是一个例子:

import java.util.*;
import java.lang.reflect.*;

public class Test {

    public void foo(List<String> list) {
    }

    public static void main(String[] args) throws Exception{
        Method method = Test.class.getMethod("foo", List.class);
        Type parameterType = method.getGenericParameterTypes()[0];
        System.out.println(parameterType);
    }
}

This prints out: 打印出:

java.util.List<java.lang.String>

So that type information has been retained in the metadata for the method. 因此,类型信息已保留在方法的元数据中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM