【问题标题】:Displaying generic type parameters from compiled class files从编译的类文件中显示泛型类型参数
【发布时间】:2012-08-15 08:23:17
【问题描述】:

是否有类似于 javap 的工具可以显示方法和字段及其原始(非擦除)类型?

我知道编译源代码时类型信息是erased。但是,编译器必须以某种方式知道,因为即使库已经编译到类文件中,它也能够确定我对库方法的调用是否匹配它们的签名。所以至少在理论上,应该可以检索到类型信息。

我进一步搜索并找到了这个答案: Where are generic types stored in java class files? 这向我指出了getGeneric...() 方法。所以在我看来,类型信息以某种复杂的方式存储在类文件中,这些方法允许获取它。但到目前为止,我还没有找到可以显示此信息的(命令行)工具。

【问题讨论】:

  • 由于javap 是一个命令行工具,似乎不能满足您的需求,您需要更准确地指定您的标准。
  • @BenSchulz 我相信我做到了:...工具...可以显示具有原始(未擦除)类型的方法和字段?

标签: java generics javap


【解决方案1】:

您使用的是旧版本的javap

$ javap -version
1.7.0

$ javap java.util.List
Compiled from "List.java"
public interface java.util.List<E> extends java.util.Collection<E> {
  public abstract int size();
  public abstract boolean isEmpty();
  public abstract boolean contains(java.lang.Object);
  public abstract java.util.Iterator<E> iterator();
  public abstract java.lang.Object[] toArray();
  public abstract <T extends java/lang/Object> T[] toArray(T[]);
  public abstract boolean add(E);
  public abstract boolean remove(java.lang.Object);
  public abstract boolean containsAll(java.util.Collection<?>);
  public abstract boolean addAll(java.util.Collection<? extends E>);
  public abstract boolean addAll(int, java.util.Collection<? extends E>);
  public abstract boolean removeAll(java.util.Collection<?>);
  public abstract boolean retainAll(java.util.Collection<?>);
  public abstract void clear();
  public abstract boolean equals(java.lang.Object);
  public abstract int hashCode();
  public abstract E get(int);
  public abstract E set(int, E);
  public abstract void add(int, E);
  public abstract E remove(int);
  public abstract int indexOf(java.lang.Object);
  public abstract int lastIndexOf(java.lang.Object);
  public abstract java.util.ListIterator<E> listIterator();
  public abstract java.util.ListIterator<E> listIterator(int);
  public abstract java.util.List<E> subList(int, int);
}

【讨论】:

  • 谢谢,我不知道 JDK7 javap 会这样做(我使用的是 JDK6,而 javap 没有显示泛型类型信息)。
【解决方案2】:

http://java.decompiler.free.fr/ 等反编译器将为您提供原始源代码的近似值,包括通用签名。

【讨论】:

    【解决方案3】:

    .class 中查看周围的一个非常好的工具是JClasslib。这是比javap 更好的选择。示例截图:

    您可以使用它来查看.class 文件中的所有字段、所有方法、字节码以及所有内容。它还可以打开 JAR 文件。

    您可以查看“属性”部分 -> 签名。您可以在那里找到此类信息。

    例如:对于下面的类定义:

    public class BlaType<T extends Integer>
    

    我可以看到这样的东西:

    【讨论】:

      【解决方案4】:

      您可以尝试Method.toGenericString(),它似乎可以在运行时从类中获得一切。此方法应打印带有通用边界的方法签名。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-10-09
        • 1970-01-01
        • 1970-01-01
        • 2016-11-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多