加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

JVM / Java是在运行时强制执行的方法可访问性规则吗?

发布时间:2020-12-15 05:07:17 所属栏目:Java 来源:网络整理
导读:我很好奇JVM是如何工作的. JVM是否确认方法可访问性规则,如“private”受保护或仅在编译时完成? 例如,是否可以在第37行附近进行一些字节码操作并调用受保护的方法,比如test3?通常编译器不会让我调用该方法,因为它被声明为protected.但我很好奇是否在运行时
我很好奇JVM是如何工作的. JVM是否确认方法可访问性规则,如“private”受保护或仅在编译时完成?

例如,是否可以在第37行附近进行一些字节码操作并调用受保护的方法,比如test3?通常编译器不会让我调用该方法,因为它被声明为protected.但我很好奇是否在运行时强制执行受保护的规则?

u.test1();
//在运行时是否可以通过字节码操作调用’test3′
// @ line37

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!

15.12.4 Runtime Evaluation of Method Invocation
At run time,method invocation requires five steps. First,a target reference may be computed. Second,the argument expressions are evaluated. Third,the accessibility of the method to be invoked is checked. Fourth,the actual code for the method to be executed is located. Fifth,a new activation frame is created,synchronization is performed if necessary,and control is transferred to the method code.

JLS的措辞表明将在运行时检查可访问性.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读