Displaying generic type parameters from compiled class files

我们两清 提交于 2020-01-02 17:41:19

问题


Is there a tool similar to javap that could display methods and fields with their original (non-erased) types?

I know that the type information is erased when source code is compiled. However, the compiler must know somehow, because it is able to determine if my calls to library methods match their signatures even if the library is already compiled into class files. So at least in theory, it should be possible to retrieve the type information.

I searched further and I found this answer: Where are generic types stored in java class files? which pointed me to getGeneric...() methods. So it looks to me that the type information is stored in class files in some complicated way, and these methods allow to obtain it. But so far I didn't find a (command line) tool that'd display this information.


回答1:


A decompiler such as http://java.decompiler.free.fr/ will give you an approximation to the original source code, including the generic signatures.




回答2:


You are using an old version of 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);
}



回答3:


A very good tool for looking around in a .class is JClasslib. It's a much better alternative than javap. An example screenshot:

You can use it to view all fields inside a .class file, all methods, the byte code, everything. It can also open JAR files.

You can look in the "Attributes" Section -> Signature. You can find such information there.

For example: For the following class definition:

public class BlaType<T extends Integer>

I can see something like this:




回答4:


You can try Method.toGenericString() and it seems everything that you can get from class in runtime. This method should print method signature with generic boundaries.



来源:https://stackoverflow.com/questions/11966091/displaying-generic-type-parameters-from-compiled-class-files

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!