【问题标题】:Is access checked at compile time or run time? [duplicate]是在编译时还是运行时检查访问? [复制]
【发布时间】:2012-12-14 04:30:03
【问题描述】:

可能重复:
JVM/Java, are method accessibility rules enforced at runtime?

当使用具有公共和私有字段和成员的类时,是否在编译时或运行时检查代码是否存在访问冲突(例如,尝试从外部类访问私有字段)?还是两者兼有?

【问题讨论】:

    标签: java oop


    【解决方案1】:

    两者兼而有之。如果你尝试编译试图访问不可访问的对象或方法的代码,你会得到编译时错误:

    field has private access in package.Class
    

    此外,当您的类尝试在运行时访问某个字段时,JVM 会检查访问:

    Exception in thread "main" java.lang.IllegalAccessError: tried to access field package.Class.field from class YourClass
    

    【讨论】:

    【解决方案2】:

    在编译时检查。我尝试了以下两个类:

    class A { 
        private int i;
    }
    

    class B { 
        private void test() {
            A a = new A();
            a.i = 5;
        }   
    }
    

    当我尝试编译B.java时,出现以下错误:

    B.java:4: i has private access in A
            a.i = 5;
             ^
    1 error
    

    但是,请记住,这个简单的示例仅适用于基本情况。当考虑反射时,这种行为可能会改变,即变量的名称仅在运行时确定。在这种情况下,无法在编译时检查访问修饰符,并且必须将检查推迟到运行时。

    【讨论】:

    • 尽管所有这些反射方法,getField()getMethod(),等等。确实会强迫您处理这种可能性,因为它们会抛出已检查的异常。
    【解决方案3】:

    在这两种情况下。在编译时很容易看到。但是在运行时测试也不难。创建2个类

    public class Test1 {
        public static void main(String[] args) throws Exception {
            Test2.hello();
        }
    }
    
    public class Test2 {
        static void hello() {
            System.out.println("hello");
        }
    }
    

    编译运行java Test1,运行正常

    现在将 Test2 更改为

    priivate static void hello() {
        System.out.println("hello");
    }
    

    并单独编译,使Test1.class不变。运行java Test1。你会得到

    Exception in thread "main" java.lang.IllegalAccessError: tried to access method Test2.hello()V from class Test1
        at Test1.main(Test1.java:5)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-18
      • 2013-08-29
      • 2018-01-17
      • 2012-06-26
      • 1970-01-01
      • 2017-08-25
      • 2013-09-17
      • 1970-01-01
      相关资源
      最近更新 更多