- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
考虑这段代码:
public class TopLevelClass {
Cloneable c = new Cloneable() {
private int privateField;
private void privateMethod() {};
};
}
有一个匿名类有一个private
成员字段和一个 private
成员方法。编译成功。
然后考虑这个:
public class TopLevelClass {
Cloneable c = new Cloneable() {
private class PrivateInnerClass {}
};
}
有一个匿名类有一个private
成员(member)类。然而……
error: modifier private not allowed here
Illegal modifier for the local class PrivateInnerClass; only abstract or final is permitted
真的是本地类吗?什么? 为什么匿名类不能有public
, protected
或 private
(以下简称those
)成员类同时可以拥有those
成员字段和方法? 困惑,我调查了 JLS。由于 Eclipse 所说,我调查了 local classes第一:
14.3. Local Class Declarations
A local class is a nested class (§8) that is not a member of any class and that has a name (§6.2, §6.7).
It is a compile-time error if a local class declaration contains any of the access modifierspublic
,protected
, orprivate
(§6.6), or the modifierstatic
(§8.1.1).
所以本地类不能有those
修饰符。但是PrivateInnerClass
是匿名Cloneable
的成员, 所以它不是本地类并且仍然能够拥有 those
修饰符。
然后我查看了class modifiers :
8.1.1. Class Modifiers
The access modifier
public
(§6.6) pertains only to top level classes (§7.6) and to member classes (§8.5), not to local classes (§14.3) or anonymous classes (§15.9.5).
The access modifiersprotected
andprivate
(§6.6) pertain only to member classes within a directly enclosing class or enum declaration (§8.5).
但是PrivateInnerClass
是一个成员类,它在一个直接封闭的类中,匿名Cloneable
, 所以它仍然可以有 those
理论上的修饰符。其他部分我也看了,还是没找到相关规定。
那么 Java 语言规范的哪一部分说匿名类的成员类不能有 those
修饰符?
附注1:有些回答对成员类和局部类争论不休,所以我做了一个测试可以得出结论(除非修饰符很重要):
Cloneable
既不是成员类也不是本地类。PrivateInnerClass
是成员类,但不是本地类。以下是我的测试代码:
public class TopLevelClass {
Cloneable c = new Cloneable() {
class PrivateInnerClass {}
};
public static void main(String[] args) throws ClassNotFoundException {
Class<?> c1 = Class.forName("TopLevelClass$1");
Class<?> c2 = Class.forName("TopLevelClass$1$PrivateInnerClass");
System.out.println(c1.isMemberClass()); // false
System.out.println(c1.isLocalClass()); // false
System.out.println(c2.isMemberClass()); // true
System.out.println(c2.isLocalClass()); // false
}
}
附注2:查看普通类(JLS §8.1)的声明:
NormalClassDeclaration: ClassModifiersopt class Identifier TypeParametersopt Superopt Interfacesopt ClassBody
据我了解,当 Identifier
类是XXX类,什么§8.1.1 stated 正在限制 Identifier
的修饰符,而不是 ClassBody
中其他声明中的修饰符的 Identifier
.否则,匿名类甚至不能有those
成员字段和方法。
任何答案,尤其是不同意附注 2 的答案,都必须指出原因 those
允许成员字段和方法。
附注3:如果您认为JLS没有这部分,您仍然需要提供一份可靠的文件来解释为什么those
成员类被禁止以及为什么those
允许成员字段和方法。
最佳答案
你有:
TopLevelClass
:未嵌套(因此被命名,不是本地的,不是匿名的)Clonable
并且不是任何类的成员的无名类:是匿名的(内部类,不是成员,在本地范围但不是“本地类”) PrivateInnerClass
,匿名类的成员:是嵌套的,不是本地的,不是匿名的,是非静态的内部类您在 (2) 中使用了修饰符 private
。您包含的 JLS 文本说明这是非法的:
8.1.1
The access modifier public (§6.6) pertains only to top level classes (§7.6) and to member classes (§8.5), not to local classes (§14.3) or anonymous classes (§15.9.5). The access modifiers protected and private (§6.6) pertain only to member classes within a directly enclosing class or enum declaration (§8.5).
即您不能在匿名类的内部(范围内)使用这些修饰符中的任何一个。
额外注释 2 的答案:
In my understanding, when the Identifier class is an XXX class, what §8.1.1 stated is restricting the modifier of Identifier, not the modifiers in other declarations in ClassBody of Identifier. Otherwise, anonymous classes even cannot have those member fields and methods.
标识符前修饰符的限制
public
可以在顶级类标识符之前应用这是为什么?
因为成员类可以被其他类直接引用(通过顶级类的“成员链”),但是本地/匿名类永远不能被外部引用。本地/匿名类声明隐藏在 java 程序的任何其他部分本身无法访问的范围内。
当其他类可访问时,修饰符仅在类声明之前是合法的。
修饰符在ClassBody内的限制
如果java程序的其他部分不能访问一个类标识符/声明,当然,ClassBody也不能访问。
因此,只要标识符之前的修饰符是非法的,修饰符在 ClassBody 中就没有可能的语义意义。
ClassBody 中是否允许修饰符的规则必须始终与标识符之前是否允许修饰符的规则相同。
所以 8.1.1。在两个地方限制修饰符
:)
关于java - JLS哪一部分说匿名类不能有public/protected/private成员类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17484834/
所以 promises 对我来说是相当新的,但我喜欢这个想法。 之前... 我以前用过这个,它只在文件被完全读取并按预期工作后才简单地返回数据: function something{ fo
当我尝试编译时出现以下错误: In member function 'double search::IDAstar::dfs(const State&, double)': 153:18: erro
最接近下面的是什么?不幸的是,下面的方法名称编译错误。 int val = delegate(string s) { return 1; }("test"); 我也尝试了 (...)=>{..
1、评论提交超时: 大家可能会发现,在提交评论非常缓慢时最容易出现“匿名”现象,这种情况主要是由于评论提交时执行时间过长引起的,可能是装了比较耗时的插件(比如Akismet等);很多博
我想在同一个表中使用一个键插入一个匿名表,如下所示: loadstring( [[return { a = "One", b = a.." two" }]] ) 在我看来,这应该返回下表: {
有人知道免费的匿名 smtp 服务吗?我想让我的应用程序的用户能够偶尔向我发送一封匿名电子邮件,而无需配置输入他们电子邮件帐户的服务器。我想我可以为此目的设置一个 gmail 帐户并将凭据嵌入到应用程
我有这个数据补丁: ALTER TABLE MY_TABLE ADD new_id number; DECLARE MAX_ID NUMBER; BEGIN SELECT max(id)
假设我有以下数据框。 Person_info (Bob, 2) (John, 1) (Bek, 10) (Bob, 6) 我想通过保持它们的值(value)来匿名。 Person_info (Pers
根据多个国家/地区的法律要求,我们在日志文件中匿名化用户的 IP 地址。使用 IPv4,我们通常只是匿名化最后两个字节,例如。而不是 255.255.255.255我们记录255.255.\*.\*
我正在学习有关 Scala 的更多信息,但在理解 http://www.scala-lang.org/node/135 中的匿名函数示例时遇到了一些麻烦。 .我复制了下面的整个代码块: object
我正在开设一个 Commerce 网上商店。 我想添加 Commerce 愿望 list ,但现在该模块仅适用于注册用户,因为未注册它不起作用。 我将显示 block 中的角色设置为匿名,但即使在更改
我正在使用发现的 Google Apps 脚本 here让匿名用户将文件上传到我的 Google 云端硬盘。 我想要的是脚本使用表单上输入的名称创建一个文件夹,然后将文件存放在该文件夹中。 到目前为止
我遇到的情况是,我正在等待一些事件的发生。我看到很多关于如何使用命名函数使用 setTimeout 的好例子,但是有没有办法使用某种匿名方法来设置超时? 代码目前看起来像这样: testForObje
我一直在阅读一些关于 Android 内存泄漏的文章,并观看了来自 Google I/O 的这个有趣的视频 on the subject . 尽管如此,我仍然不完全理解这个概念,尤其是当它对用户安全或
我正在尝试适应 Spring JDBC,但让我烦恼的是使用这些匿名类,我们不能传递任何局部变量,除非它们是最终的,这可能很容易安排,但是如果我需要循环一个怎么办?数组还是集合?我无法将“FedMode
我正在尝试将数据输入到 Oracle 数据库中。这将是一个带有多个参数的存储过程……我的意思是像 27 个参数(别问,我没有设计它)…… 现在我必须以某种方式填充此存储过程的参数...存储过程采用的大
我之前问过这个问题:Combine a PartialFunction with a regular function 然后意识到,我实际上并没有问对。 所以,这是另一个尝试。 如果我这样做: va
我想从 C++ 执行一个匿名的 Qt 脚本函数,但不知道要使用的 QScriptContext。 这是脚本: { otherObject.Text = "Hello World"; setTi
我有一个返回 promise 的函数。 (本例中为 foo) 我尝试在声明为匿名的解析函数中调用此函数。 我已经尝试过使用this 但这不起作用。 我的代码是这样的 var foo = functio
这个问题的灵感来自这个 excellent example .我有 ASP.NET Core MVC 应用程序,我正在编写 unit tests为 Controller 。其中一种方法返回带有匿名类型
我是一名优秀的程序员,十分优秀!