Skip to content

Instantly share code, notes, and snippets.

@suztomo
Created September 16, 2020 15:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save suztomo/824af5f08eb9c0f2407ecb335e2ccd77 to your computer and use it in GitHub Desktop.
Save suztomo/824af5f08eb9c0f2407ecb335e2ccd77 to your computer and use it in GitHub Desktop.
checkcast throws a runtime exception

foo/A.java

package foo;

public class A {

  public static final A f = new B();
}

foo/B.java

package foo;

// We change this modifier to non-public.
public class B extends A {

}

bar/C.java

package bar;

import foo.A;
import foo.B;

public class C {
  public static void main(String[] arguments) {
A a = A.f;
B b = (B) a;
System.out.println(b);
  }
}

When we change the modifier of B to non-public, the cast throws this exception.

suztomo-macbookpro44% java -cp  target/classes:b-public.jar bar.C
Exception in thread "main" java.lang.IllegalAccessError: tried to access class foo.B from class bar.C
	at bar.C.main(C.java:28)
suztomo-macbookpro44% javap -verbose -cp b-public.jar bar.C      
Classfile jar:file:/Users/suztomo/wsgenoptions/b-public.jar!/bar/C.class
  Last modified Sep 16, 2020; size 602 bytes
  MD5 checksum 13904c440cdf46f7f4d611c30bb0d77b
  Compiled from "C.java"
public class bar.C
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #7.#25         // java/lang/Object."<init>":()V
   #2 = Fieldref           #26.#27        // foo/A.f:Lfoo/A;
   #3 = Class              #28            // foo/B
   #4 = Fieldref           #29.#30        // java/lang/System.out:Ljava/io/PrintStream;
   #5 = Methodref          #31.#32        // java/io/PrintStream.println:(Ljava/lang/Object;)V
   #6 = Class              #33            // bar/C
   #7 = Class              #34            // java/lang/Object
   #8 = Utf8               <init>
   #9 = Utf8               ()V
  #10 = Utf8               Code
  #11 = Utf8               LineNumberTable
  #12 = Utf8               LocalVariableTable
  #13 = Utf8               this
  #14 = Utf8               Lbar/C;
  #15 = Utf8               main
  #16 = Utf8               ([Ljava/lang/String;)V
  #17 = Utf8               arguments
  #18 = Utf8               [Ljava/lang/String;
  #19 = Utf8               a
  #20 = Utf8               Lfoo/A;
  #21 = Utf8               b
  #22 = Utf8               Lfoo/B;
  #23 = Utf8               SourceFile
  #24 = Utf8               C.java
  #25 = NameAndType        #8:#9          // "<init>":()V
  #26 = Class              #35            // foo/A
  #27 = NameAndType        #36:#20        // f:Lfoo/A;
  #28 = Utf8               foo/B
  #29 = Class              #37            // java/lang/System
  #30 = NameAndType        #38:#39        // out:Ljava/io/PrintStream;
  #31 = Class              #40            // java/io/PrintStream
  #32 = NameAndType        #41:#42        // println:(Ljava/lang/Object;)V
  #33 = Utf8               bar/C
  #34 = Utf8               java/lang/Object
  #35 = Utf8               foo/A
  #36 = Utf8               f
  #37 = Utf8               java/lang/System
  #38 = Utf8               out
  #39 = Utf8               Ljava/io/PrintStream;
  #40 = Utf8               java/io/PrintStream
  #41 = Utf8               println
  #42 = Utf8               (Ljava/lang/Object;)V
{
  public bar.C();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 25: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lbar/C;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=3, args_size=1
         0: getstatic     #2                  // Field foo/A.f:Lfoo/A;
         3: astore_1
         4: aload_1
         5: checkcast     #3                  // class foo/B
         8: astore_2
         9: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
        12: aload_2
        13: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
        16: return
      LineNumberTable:
        line 27: 0
        line 28: 4
        line 29: 9
        line 30: 16
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      17     0 arguments   [Ljava/lang/String;
            4      13     1     a   Lfoo/A;
            9       8     2     b   Lfoo/B;
}
SourceFile: "C.java"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment