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.
A decompiler such as http://java.decompiler.free.fr/ will give you an approximation to the original source code, including the generic signatures.
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);
}
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:
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.