java – 运行时私有,公共,包关键字之间有什么区别吗?

我知道Java有这些serval关键字来识别开发过程中的变量范围,但是我想知道它在生产环境中是否有所不同,或者只是为了编码器的兴趣?谢谢.
最佳答案
可访问性也在运行时强制执行.如果某些代码尝试访问不应该访问的成员,则抛出IllegalAccessException或IllegalAccessError.这是一个快速演示:

public class AccessTest {
    public int publicNumber;
    private int secretNumber;
}

public class Client {
    public static void main(String[] args) throws Exception {
        reflection();
        noReflection();
    }

    private static void noReflection() throws IllegalAccessException, NoSuchFieldException {
        int a = new AccessTest().publicNumber;
          //                     ^^^^^^^^^^^^ 
          // To be changed to secretNumber in bytecode editor after compilation

        System.out.println("Number read: " + a);
    }

    private static void reflection() throws IllegalAccessException, NoSuchFieldException {
        AccessTest instance = new AccessTest();
        AccessTest.class.getDeclaredField("publicNumber").get(instance); // <-- Works
        try {
            AccessTest.class.getDeclaredField("secretNumber").get(instance); // <-- Throws IllegalAccessException
        } catch (IllegalAccessException e) {
            System.out.println("Caught IllegalAccessException");
        }
    }
}

用反射:

实际上,上述程序输出:

Caught IllegalAccessException
Number read: 10

没有反思:

当我使用字节码编辑器进行更改时

getfield com/blah/access/AccessTest/publicNumber I

在方法noReflection()中:

getfield com/blah/access/AccessTest/secretNumber I

输出是:

Caught IllegalAccessException
Exception in thread "main" java.lang.IllegalAccessError: tried to access field com.blah.access.AccessTest.secretNumber from class com.blah.access.Client
at com.blah.access.Client.noReflection(Client.java)
at com.blah.access.Client.main(Client.java:12)

正如迈克尔所说,这种行为可能与JVM有关.我跑了这个

java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) 64-Bit Server VM (build 16.3-b01, mixed mode)

转载注明原文:java – 运行时私有,公共,包关键字之间有什么区别吗? - 代码日志