如何使Groovy方法真正受到保护

时间:2014-07-05 00:27:59

标签: groovy

尝试在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 Documentation

  

Groovy中的受保护与Java中受保护的含义相同,即   你可以在同一个包中拥有朋友,派生类也可以   见保护成员。

好的,如果protected在Groovy中具有相同的含义但未强制执行,那是否会侵蚀其含义?也许我错过了什么,

2 个答案:

答案 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超级怪人对你问题提出的问题的看法......