JVM / Java是在运行时强制执行的方法可访问性规则吗?
我很好奇JVM是如何工作的. JVM是否确认方法可访问性规则,如“private”受保护或仅在编译时完成?
例如,是否可以在第37行附近进行一些字节码操作并调用受保护的方法,比如test3?通常编译器不会让我调用该方法,因为它被声明为protected.但我很好奇是否在运行时强制执行受保护的规则? u.test1(); package org.berlin.algo.basic.test; public class RunX { private String zzz = "rrrrr"; public void test1() { // Note: I am intentionally use 'new' here as part of my test,not a // good practice I know but allowed by the language. Object x = new String("Test1 -----[1.1] " + zzz); x = new String("Test1 --- [1.2]" + x.toString()); System.out.println(x); this.test2(); this.test3(); } /** * Here,I noticed that the compiler removed my 'test2' code block. * Does that always happen? */ private void test2() { Object x = new String("Test2@line21--->>> [2.1]"); System.out.println(x); } protected void test3() { Object x = new String("Test3@line27 {Will the JVM enforce the 'protected' method rule for test3? --->>> [3.1]"); x = new String("Test3@line28--->>> [3.2]"); System.out.println(x); } public static void main(final String [] args) { System.out.println("Running"); RunX u = new RunX(); u.test1(); // Is it possible at runtime,to call 'test3' through bytecode manipulation // @line37 System.out.println("Done"); } } // End of the Class // /* JVM bytecode: javap -v RunX Compiled from "RunX.java" public class org.berlin.algo.basic.test.RunX extends java.lang.Object SourceFile: "RunX.java" minor version: 0 major version: 50 Constant pool: const #1 = class #2; // org/berlin/algo/basic/test/RunX const #2 = Asciz org/berlin/algo/basic/test/RunX; ... ... const #84 = Asciz SourceFile; const #85 = Asciz RunX.java; { public org.berlin.algo.basic.test.RunX(); Code: Stack=2,Locals=1,Args_size=1 0: aload_0 1: invokespecial #10; //Method java/lang/Object."<init>":()V 4: aload_0 5: ldc #12; //String rrrrr 7: putfield #14; //Field zzz:Ljava/lang/String; 10: return LineNumberTable: line 3: 0 line 5: 4 line 3: 10 LocalVariableTable: Start Length Slot Name Signature 0 11 0 this Lorg/berlin/algo/basic/test/RunX; public void test1(); Code: Stack=5,Locals=2,Args_size=1 0: new #21; //class java/lang/String 3: dup 4: new #23; //class java/lang/StringBuilder 7: dup 8: ldc #25; //String Test1 -----[1.1] 10: invokespecial #27; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 13: aload_0 14: getfield #14; //Field zzz:Ljava/lang/String; 17: invokevirtual #30; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 20: invokevirtual #34; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 23: invokespecial #38; //Method java/lang/String."<init>":(Ljava/lang/String;)V 26: astore_1 27: new #21; //class java/lang/String 30: dup 31: new #23; //class java/lang/StringBuilder 34: dup 35: ldc #39; //String Test1 --- [1.2] 37: invokespecial #27; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 40: aload_1 41: invokevirtual #41; //Method java/lang/Object.toString:()Ljava/lang/String; 44: invokevirtual #30; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 47: invokevirtual #34; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 50: invokespecial #38; //Method java/lang/String."<init>":(Ljava/lang/String;)V 53: astore_1 54: getstatic #42; //Field java/lang/System.out:Ljava/io/PrintStream; 57: aload_1 58: invokevirtual #48; //Method java/io/PrintStream.println:(Ljava/lang/Object;)V 61: aload_0 62: invokespecial #54; //Method test2:()V 65: aload_0 66: invokevirtual #57; //Method test3:()V 69: return LocalVariableTable: Start Length Slot Name Signature 0 70 0 this Lorg/berlin/algo/basic/test/RunX; 27 43 1 x Ljava/lang/Object; protected void test3(); Code: Stack=3,Args_size=1 0: new #21; //class java/lang/String 3: dup 4: ldc #66; //String Test3@line27 {Will the JVM enforce the 'protected' method rule for test3? --->>> [3.1] 6: invokespecial #38; //Method java/lang/String."<init>":(Ljava/lang/String;)V 9: astore_1 10: new #21; //class java/lang/String 13: dup 14: ldc #68; //String Test3@line28--->>> [3.2] 16: invokespecial #38; //Method java/lang/String."<init>":(Ljava/lang/String;)V 19: astore_1 20: getstatic #42; //Field java/lang/System.out:Ljava/io/PrintStream; 23: aload_1 24: invokevirtual #48; //Method java/io/PrintStream.println:(Ljava/lang/Object;)V 27: return LocalVariableTable: Start Length Slot Name Signature 0 28 0 this Lorg/berlin/algo/basic/test/RunX; 10 18 1 x Ljava/lang/Object; public static void main(java.lang.String[]); Code: Stack=2,Args_size=1 0: getstatic #42; //Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #72; //String Running 5: invokevirtual #74; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: new #1; //class org/berlin/algo/basic/test/RunX 11: dup 12: invokespecial #76; //Method "<init>":()V 15: astore_1 16: aload_1 17: invokevirtual #77; //Method test1:()V 20: getstatic #42; //Field java/lang/System.out:Ljava/io/PrintStream; 23: ldc #79; //String Done 25: invokevirtual #74; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 28: return LocalVariableTable: Start Length Slot Name Signature 0 29 0 args [Ljava/lang/String; 16 13 1 u Lorg/berlin/algo/basic/test/RunX; } */ 解决方法
To the JLS!
JLS的措辞表明将在运行时检查可访问性. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |