如何使Groovy方法真正受到保护
试图在groovy如何使Groovy方法真正受到保护,groovy,Groovy,试图在groovy中使方法受保护: package com.foo class Foo { protected def getSomething(){ } } 这不起作用,因为groovy默认使几乎所有内容都可见,所以我尝试使用@PackageScope package com.foo import groovy.transform.PackageScope @PacakgeScope class Foo { def getSomething(){ } }
中使方法受保护
:
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
,则不会生成错误;不太好。我不能强制用户静态编译,所以有没有其他方法可以强制执行受保护的
方法
来自Groovy
Groovy中的Protected与Java中的Protected具有相同的含义,即。
您可以在同一个包中拥有好友,派生类也可以
请参阅受保护的成员
好的,如果
protected
在Groovy中具有相同的含义,但是没有强制执行,那么这不是削弱了它的含义吗?也许我遗漏了什么,简短的回答:Groovy不强制执行可见性检查
更长的答案
Protected在Java中有一个含义,您肯定知道。我仅为感兴趣的读者提及:
Groovy并不是没有设置相同的修饰符。因此,从Java来看,成员将受到保护,就像Java本身一样。更重要的是,Groovy不在运行时(或编译时)执行可见性检查,甚至可能使用反射来强制实现可访问性。Groovy必须这样做,因为在Groovy中,访问成员的类通常是运行时的一个类。这意味着Groovy必须在运行时模拟可见性检查,但对于这种情况,需要某种类型的“调用来源”,但由于元对象协议缺乏正确传输它的能力,所以Groovy中并不总是可用的
使用@CompileStatic则不同。这里生成了对成员的直接访问。只是它应该已经编译失败了,并且在运行时不会因为Illegaccesserror而失败。这真是太让人头疼了。我刚刚搜索了“groovy信息隐藏”。外面几乎什么都没有 在Groovy中可能有一些涉及闭包的技术来获取隐藏的信息。但我只是做了一些实验,并找到了一种可能有用的方法,希望能将
@CompileStatic
。它涉及使用一个内部类,并结合从抽象类
类生成子类,如果非法尝试绕过工厂方法,则引发异常。事实上,这是一个相当复杂的过程
更重要的是,经过仔细检查,我发现即使这样也不起作用
到目前为止,我发现的唯一方法就是这样一种uber黑客,我甚至羞于提及它:一种涉及检查堆栈跟踪的技术
我很清楚,实际上@CompileStatic
更多的是关于类型检查的强制执行,而不是关于信息隐藏:它以一种更强大的注释版本@TypeChecked
的方式被覆盖
在Python中,有一种约定(我假设仍然使用),即为那些“被视为私有”的字段指定一种特殊的命名约定,即名称以双下划线开头。但我在Groovy中没有看到类似的情况
布洛赫在他的优秀著作《有效的Java》中,给出了信息隐藏非常重要的许多合理理由。当然,现在大家都知道,即使在Java中,所有这些都是脆弱的,可以通过反射技术来破解。但是我想听听一个Groovy uber极客对您的问题提出的看法…Groovy强制执行
私有
,但是公共
和受保护
的行为似乎是一样的。我猜@CompileStatic
是唯一的选项,请注意,Groovy没有像Java那样强制私有。如果您有一个子类实例,则无法访问超类的私有成员,但仅此而已。如果您用一个私有字段定义一个类Foo,并访问Foo实例(不是Foo的子类)上的字段,那么在Groovy中您可以访问该字段。@blackdrag感谢您指出了这个微妙之处。我想,显而易见的“反应”是将所有具有此类私有字段的类抽象化。。。