尝试在groovy protected
中创建一个方法:
package com.foo
class Foo {
protected def getSomething(){
}
}
这不起作用,因为groovy默认情况下几乎所有内容都可见,所以我尝试使用@PackageScope
package com.foo
import groovy.transform.PackageScope
@PacakgeScope
class Foo {
def getSomething(){
}
}
此类工作,但仅在调用者使用@CompileStatic
...
package com.bar
class Bar {
@CompileStatic
static void main(args){
def f = new Foo()
println f.getSomething()
}
以上抛出IllegalAccessError
,这很好,但没有@CompileStatic
,就不会产生错误;不太好看。我无法强制用户静态编译,所以有没有其他方法可以强制执行protected
方法?
Groovy中的受保护与Java中受保护的含义相同,即 你可以在同一个包中拥有朋友,派生类也可以 见保护成员。
好的,如果protected
在Groovy中具有相同的含义但未强制执行,那是否会侵蚀其含义?也许我错过了什么,
答案 0 :(得分:8)
简短回答:Groovy不强制执行可见性检查。
更长的答案 受保护在Java中有意义,你肯定知道。我只是为感兴趣的读者提到它:http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6.2
Groovy并不是设置相同的修饰符。从Java看,成员将像Java本身一样受到保护。 Groovy不会在运行时(或编译时)执行可见性检查,甚至可能使用反射来强制访问。 Groovy必须这样做,因为通常在Groovy中,访问该成员的类是运行时之一。这意味着Groovy必须在运行时模拟可见性检查,但为此需要某种“调用原点”,但由于元对象协议缺乏正确传输它的能力,因此Groovy并不总是可用。
使用@CompileStatic的东西是不同的。这里可以直接访问该成员。只有它应该已经编译失败并且在运行时不会因IllegalAccessError而失败。
答案 1 :(得分:1)
这令人头疼。我刚刚搜索了#34; groovy信息隐藏"。那里几乎没有任何东西!
可能存在涉及闭包以在Groovy中获取信息隐藏的技术。但我只是做了一些实验,并找到了一种方法,希望强加@CompileStatic
可能有用。它涉及使用内部类结合来自abstract
类的子类,并在非法尝试绕过工厂方法时抛出异常。事实上,这真是一场黑客攻击。
更重要的是,经过仔细检查,我发现即使这样也没有用。
我到目前为止找到的唯一方法就是这样一个超级黑客,我甚至提到它感到羞愧:涉及检查堆栈跟踪的技术。
在使用 Groovy In Action 2nd Ed。进行回访时,我明白实际上@CompileStatic
更多地是关于类型检查的执行而不是与信息有关的任何事情-hiding:它被覆盖的方式使它成为注释@TypeChecked
的一个更强大的版本。
在Python中,有一种惯例,我认为仍然使用,给出了被视为私有的字段"一种特殊的命名约定,即使名称以双下划线开头。但是我在Groovy中没有看到这些内容。
Bloch,在他出色的着作 Effective Java 中,提供了很多合理的理由,说明信息隐藏非常重要。当然,现在众所周知,即使在Java中,所有这些都是脆弱的,并且可以通过反射技术来破解。但我想听听Groovy超级怪人对你问题提出的问题的看法......