- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我发现了一个奇怪的编译限制,我无法解释,我不明白这个限制的原因。
示例 1:
考虑这些类:
在包e1;
:
public class C1 {
enum E1 { A, B, C }
public E1 x;
}
在包e2;
:
import e1.C1;
public class C2 {
public String test(C1 c1) {
return c1.x.toString(); // here compilation error
}
}
这会导致以下编译错误:
Error:(5,20) java:
toString()
injava.lang.Enum
is defined in an inaccessible class or interface
示例 2:
考虑这些类:
在包i1;
:
public interface I1 {
int someMethod();
}
public class C1 {
static class I2 implements I1 {
public int someMethod() {
return 1;
}
}
public I2 x = new I2();
}
在i2包中;
:
import i1.C1;
import i1.I1;
public class C2 {
public static void main(String[] args) {
C1 c1 = new C1();
System.out.println(c1.x.someMethod()); // compilation error
}
}
这也会导致相同的编译错误,但如果我们将违规行更改为:
System.out.println(((I1)c1.x).someMethod());
然后可以编译并正常工作。
所以,问题是:
为什么需要这种可访问性限制?
是的,我知道 example-1) 中的类 C1.E
和 example-2) 中的 C1.I2
类是包私有(private)的。 但同时很明显,没有人可以为基接口(interface)(I1
of Object
)的方法分配较弱的访问权限,因此直接使用总是安全的将对象转换为其基本接口(interface)并访问受限方法。
有人能解释一下这个限制的目的和原因吗?
A member (class, interface, field, or method) of a reference (class, interface, or array) type or a constructor of a class type is accessible only if the type is accessible...
看起来这是限制,但它没有解释为什么需要这个限制(在上述示例的情况下)...
最佳答案
用于调用实例方法invokevirtual使用指令。要调用这个方法类必须有一个对该方法的解析引用
来自invokevirtual规范:
Linking Exceptions
During resolution of the symbolic reference to the method, any of the exceptions pertaining to method resolution (§5.4.3.3) can be thrown.
5.4.3.3。方法解析:
To resolve an unresolved symbolic reference from D to a method in a class C, the symbolic reference to C given by the method reference is first resolved (§5.4.3.1).
5.4.3.1。类和接口(interface)解析:
If C is not accessible (§5.4.4) to D, class or interface resolution throws an IllegalAccessError.
5.4.4。访问控制:
A class or interface C is accessible to a class or interface D if and only if either of the following conditions is true:
C is public.
C and D are members of the same run-time package (§5.3).
C 和 D 不是来自同一个包。所以即使java为你编译了这段代码,它也会在调用过程中抛出一个IllegalAccessError。编译器足够聪明,可以防止这种明显的错误。 这些限制来自 java 的类解析过程的要求。
要调用实例方法,JVM 需要两件事:对对象的引用和对象(类或接口(interface))的描述。通过 resolution process 访问描述.如果失败,则调用失败。
If an error occurs during resolution of a symbolic reference, then an instance of IncompatibleClassChangeError (or a subclass) must be thrown at a point in the program that (directly or indirectly) uses the symbolic reference.
在您的情况下,C2 可以访问 I1。所以接口(interface)调用效果很好。但 C2 无权访问 I2 类。这就是为什么如果这段代码编译,IllegalAccessError 可能会在运行时抛出。
如何重现 IllegalAccessError:
Exception in thread "main" java.lang.IllegalAccessError: tried to access class qq.Test1$I2 from class Test at Test.main(Test.java:30)
关于java - "method ___() in ___ is defined in inaccessible class or interface"编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15722184/
我在配置单元中有一个表存储为文本文件。我想将所有数据移动到另一个具有相同架构但存储为序列文件的表中。如何创建第二个表?我想使用配置单元 create table like 命令,但它不支持 as se
我想检查用户输入。如果我在 myRange 中有一个单元格其中包含“2..4”它通过IsNumeric测试为真,这就是我寻找其他选择的原因。 如果我运行一个包含 MsgBox (TypeName(my
我正在尝试弄清楚如何正确使用 WHERE _ IN _ 语句 定义: c.execute('''CREATE TABLE IF NOT EXISTS tab ( _id integer PRI
假设,假设我想对一个可能非常大的文件执行顺序写入。 如果我 mmap() 一个巨大的区域并在整个区域上进行 madvise(MADV_SEQUENTIAL),那么我可以以相对有效的方式写入内存。我已经
我最近看到这个语法 here export interface ActionReducer { (state: T | undefined, action: V): T; } 我对语法很困惑 我
我经常看到这两个选择器,有什么区别?谢谢 最佳答案 这是一个 ID 选择器 (1) $("#el") 这是一个类选择器(2) $(".el") 所以 引用文献 All Selectors ID
显然这通常与大小有关,但我只有一个包含六列的表。 最近唯一有变化的是,今天我安装了一个论坛,但我又删除了它,问题仍然存在。 我在 PHPmyAdmin 中手动输入 SQL。 知道问题出在哪里吗? 最佳
我发现了一个奇怪的编译限制,我无法解释,我不明白这个限制的原因。 示例 1: 考虑这些类: 在包e1;: public class C1 { enum E1 { A, B, C } p
我一直在寻找解决此错误的方法,但找不到答案。不断收到此错误: Apr 06, 2018 1:40:36 PM org.springframework.web.servlet.DispatcherSer
#define TRIP 6 #include char error_area(char area_code, char S, char M, char L, char N, char P, cha
我的 ty019 数据库中有两个表,即 tya019 和 tya0191。我想从 tya019 和 cell_n 加入 csa、name、totm,从 tya0191 和两个表的 rno 放置(这是它
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 关于您编写的代码问题的问题必须在问题本身中描述具体问题 — 并且包括有效代码 以重现它。参见 SSC
我正在尝试使用枚举来表示交通模拟中的街道和方向。我遇到了一个问题,试图在我的 Vehicle 头文件中包含将枚举放入构造函数并将其放入 Vehicle 构造函数。 我在尝试编译 Vehicle.h 时
void delete_node(node_t *p, void *item) { while(p -> next != NULL && (p->next)-> item != item) {
这个问题在这里已经有了答案: "application: not a procedure" in binary arithmetic procedures (1 个回答) Getting every
我找到 cabal安装软件包时的行为令人抓狂。例如,运行 cabal install funsat 安装旧版本 array , time , random , quickcheck , 和 bitse
今天,我在博客文章评论中看到了一些奇怪的东西。有人在评论中用以下格式评论了博客标题和站点名称: ___123___POST TITLE – SITE NAME___123___ 我用___123___
我已经使用了Pod“SinchRTC”,并且能够在 Debug模式下构建和运行项目。但是现在当我完成项目时,出现了错误:- Undefined symbols for architecture arm
我是一名六年级学生,正在尝试使用 netbeans 8.1 和 java 编写 TicTacToe 程序。 这是我到目前为止的代码(为了简单起见,我只包含一个按钮的代码): public class
这个问题已经有答案了: error in python d not defined. [duplicate] (3 个回答) 已关闭 9 年前。 在终端中运行以下代码时: import getpass
我是一名优秀的程序员,十分优秀!