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

a7qyws3x  于 2022-10-07  发布在  其他
关注(0)|答案(2)|浏览(223)

正在尝试在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中具有相同的含义,但没有被强制执行,这不会削弱它的含义吗?也许我错过了什么,

wxclj1h5

wxclj1h51#

简而言之:Groovy不强制执行可见性检查。

更长的答案受保护在Java中有一个含义,你肯定知道。我只为感兴趣的读者提一下:http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6.2

这并不是说Groovy没有设置相同的修饰符。因此,从Java的Angular 来看,成员将受到保护,就像在Java本身一样。更重要的是,Groovy不在运行时(或编译时)执行可见性检查,甚至可能使用反射来强制可访问性。Groovy必须这样做,因为通常在Groovy中,访问该成员的类是运行库之一。这意味着Groovy必须在运行时模拟可见性检查,但为此需要某种“调用源”,但在Groovy中并不总是可用的,因为元对象协议缺乏正确传输它的能力。

使用@CompileStatic则有所不同。这里产生了对成员的直接访问。只是它应该已经编译失败,并且在运行时不会因为IllegalAccessError而失败。

whlutmcx

whlutmcx2#

这是相当令人费解的。我刚刚搜索了一下“时髦的信息隐藏”。外面几乎什么都没有!

可能存在涉及闭包的技术来获取信息--隐藏在Groovy中。但我只是做了几个实验,找到了一种方法,希望能施加@CompileStatic,这可能会有一些用处。它涉及结合使用内部类和来自abstract类的子类化,并在非法尝试绕过工厂方法时引发异常。事实上,这是一次相当大的黑客攻击。

更重要的是,仔细检查后,我发现即使是这样也不起作用。

到目前为止,我发现的唯一方法是这样一种超级黑客,我甚至羞于提及它:涉及检查堆栈跟踪的技术。

关于使用*Groovy进行检查,第二版。*我很清楚,实际上@CompileStatic更多地是关于类型检查的实施,而不是任何与信息隐藏有关的事情:它被以一种更强大的版本的注解@TypeChecked的形式涵盖起来。

在Python中,有一个约定,我想它仍然在使用,即给应该“被视为私有”的字段提供一个特殊的命名约定,即使名称以双下划线开头。但我在Groovy中没有看到任何类似的东西。

Bloch在他的优秀著作《Efficient Java*》中给出了许多合理的理由,说明信息隐藏是非常重要的。当然,众所周知,即使在Java中,这一切也是脆弱的,可以通过反射技术破解。但我想听听一位Groovy超级极客对你的问题提出的问题的看法……

相关问题