JDK-7031005 : javap prints "extends java.lang.Object"
  • Type: Bug
  • Component: tools
  • Sub-Component: javap
  • Affected Version: 7
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2011-03-25
  • Updated: 2017-01-26
  • Resolved: 2011-05-17
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
7 b138Fixed
Related Reports
Relates :  
Relates :  
java version "1.7.0-ea-fastdebug"
Java(TM) SE Runtime Environment (build 1.7.0-ea-fastdebug-b135)
Java HotSpot(TM) Client VM (build 21.0-b05-fastdebug, mixed mode)

javap prints "extends java.lang.Object".

$ javap java.lang.Comparable
Compiled from "Comparable.java"
public interface java.lang.Comparable<T extends java.lang.Object> extends java.lang.Object {
  public abstract int compareTo(T);

But, javap does not print "extends java.lang.Object".

$ javap java.lang.Runnable
Compiled from "Runnable.java"
public interface java.lang.Runnable {
  public abstract void run();


This bug can be reproduced always.

EVALUATION The general issue is whether or not to include "extends java.lang.Object" in the Java signatures in javap output. This is complicated by the fact that the superclass value may be zero (for java.lang.Object itself) and is always set to java.lang.Object for interfaces. Thus for an interfaces in particular, they always have a superclass of Object as well as any superinterfaces. Ideally, there would be a way to say (with Java syntax) the superclass is unset, or is java.lang.Object or is anything else. But while you can express that for classes, you cannot express that for interfaces. When this came up before (6715757) we resolved it in favor of writing explicit superclasses, even to the extend of abusing Java syntax. For example, interface I extends java.lang.Object implements I1, I2, I3 { } Even worse, the output was inconsistent depending on whether the superclass info was taken from the class signature (for generic types) or from the class file superclass index (for non-generic types.) It is this latter case is reported in this bug, 7031005. The solution is to revert back to using standard Java syntax to express the superclass and superinterfaces, and to omit "extends java.lang.Object". Technically this is a slight loss of information, since you now cannot tell the difference between the superclass being omitted (superclass field == 0) or being specified as Object. But consistency and the simplicity of using Java syntax when printing signatures win out: if it looks like a Java signature, it should be a valid Java signature.

EVALUATION The main issue here is that javap is inconsistent depending on whether the superclass info is obtained from a generic type signature or not. Here is the table of the current behavior. In each pair of lines, the first line is the line from a .java source file, the second line is the corresponding line from the javap output: 1. class Test { class Test extends java.lang.Object { 2. class Test extends Super { class Test extends Super { 3. class Test<T> { class Test<T extends java.lang.Object> extends java.lang.Object { 4. class Test<T> extends Super { class Test<T extends java.lang.Object> extends Super { 5. interface Test { interface Test { 6. interface Test extends Super { interface Test extends Super { 7. interface Test<T> { } interface Test<T extends java.lang.Object> extends java.lang.Object { 8. interface Test<T> extends Super { interface Test<T extends java.lang.Object> extends java.lang.Object implements Super { In 1 and 3, the use of "extends java.lang.Object" is verbose but not incorrect Java code. In 7 and 8, the use of "extends java.lang.Object" and "implements Super" may well indicate the info shown in the Signature attributes, but seem confusing from a Java perspective: 7 sig: <T:Ljava/lang/Object;>Ljava/lang/Object; 8 sig: <T:Ljava/lang/Object;>Ljava/lang/Object;LSuper;