gpt4 book ai didi

java - 谁能解释 Proguard 配置设置 : -keep @interface *

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:31:16 24 4
gpt4 key购买 nike

这是有问题的配置设置:-keep @interface *

这篇文章中引用了此设置:https://stackoverflow.com/a/17437740/367544

Proguard 手册中的此处:https://www.guardsquare.com/en/proguard/manual/troubleshooting#notkept

但手册(或帖子)并未解释此配置设置的工作原理或原因。我认为此配置值会保留在您的应用程序中定义 的任何注释。我在这里强调 defined 这个词是因为我想将它与 used 注释的地方进行比较。因此,如果我在我的代码中定义了一个注释,如 public @interface MyAnnotation {}那么我希望这个配置设置能够保留它。但是,如果我要在另一个类中使用我的注释,如 public class MyClass { @MyAnnotation public void run(){} }那么我希望此配置设置保留在那里。我认为要在使用注释的地方保留注释,您需要像 -keep class * { @interface <methods>; } 这样的设置。 .但是,我的理解显然是错误的,因为 -keep @interface *配置设置确实使用的地方保留注释。

谁能解释为什么 -keep @interface *配置设置会影响在其他类中使用的注释吗?此外,Proguard 手册从未解释如何使用 @interface关键字。这就像任何注释的通配符吗?或者它是否像我的示例中那样引用注释的定义 public @interface MyAnnotation {} ?还是完全不同?

最佳答案

当每个接口(interface)都被编译时,即使使用混淆器,它也应该创建一个可以在 java 虚拟机中使用的有效类文件。Java 有特定的命名规则,用于将包中的接口(interface)和类与文件连接起来。

所以例如即使接口(interface)VeryImportantInterface包裹数量 com.mycompany.mypackage被混淆了,结果你得到:界面 a在包装内 b.c.d java 期望找到接口(interface) a在包装内 b.c.d在名为 a.class 的文件中

类似的规则适用于内部类和接口(interface)。

因此,如果您确实混淆了类或接口(interface)的定义,则必须在任何地方都提及其混淆后的名称。否则,例如类 MyClass.class混淆为 a.class和另一类,例如MyClassReference仍将此类引用为 MyClass然后是ClassNotFoundException将在 MyClassReference 时抛出尝试使用 MyClass第一次。

关于-keep @interface *ProGuard RefCard 中所述

'keep' prevents classes and class members from being removed or renamed.

ProGuard RefCard还提到通配符 *可以用

  1. * can be used for any number of characters (but not the package separator)
  2. the class name * refers to any class, irrespective of its package.
  3. * matches any field or method

所以 -keep @interface *根据以上定义适用于 public @interface MyAnnotation {}因为它的名字匹配通配符 * .因为根据定义 MyAnnotation不会被删除,它不会从任何地方删除。

相反-keep class * { @interface <methods>; }更具体,只会保留注释的用法。

要考虑的另一件事是 keep后面跟着一个 Class specification .并基于 Class specification

The @ specifications can be used to restrict classes and class members to the ones that are annotated with the specified annotation types. An annotationtype is specified just like a classname.

pro guard在收缩过程中会删除所有直接或间接使用的方法和成员加上-keep指定的方法和成员.但是它没有明确提及它对注释的作用。Pro-Guard 提到缩小以下内容:

By default, shrinking is applied; all classes and class members are removed, except for the ones listed by the various -keep options, and the ones on which they depend, directly or indirectly. Shrinking Options So one case could be that pro-guard somehow detects that the annotation is used and prevents it from beeing removed during shrinking. Another case would be that the annotations are considered metadatum of the methods and not beeing considered members. It is really not obvious or well documented in proguard documentation.

您可以使用 -whyareyoukeeping @interface *-verbose从 Prog-Guard 获得有关保留相关接口(interface)的原因的反馈。

更新:由于上述配置指令的结果是: ... is kept by a directive in the configuration. , 只能得出结论 -keep @interface *实际上 。因此,它没有提供任何额外的说明。在没有对 Pro-Guard 文档进行任何具体解释的情况下,我认为可能有以下 2 种可能的解释:1. proguard shrinking step 认为注释在代码的某些部分使用,因此需要并且不减少。2. class_specification @interface *匹配带注释的方法和注释声明。

关于java - 谁能解释 Proguard 配置设置 : -keep @interface *,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49962245/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com