合成方法的惩罚是什么? [英] What's the penalty for Synthetic methods?

查看:105
本文介绍了合成方法的惩罚是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Eclipse下开发Java应用程序时,我收到了关于通过合成方法访问的方法/值的警告。解决方案只是将私有访问修饰符更改为默认级别。

While developing a Java application under Eclipse I got the warning about "method/value accessed via a synthetic method". The solution was simply changing a private access modifier to a default level.

这让我想知道:使用合成方法的惩罚是什么?有一些?我假设编译器/ Eclipse会引发警告,但它是如此相关或可以安全忽略的东西?

That left me wondering: what's the penalty on using a synthetic method? There is some? I assume so as the compiler/Eclipse raises the warning, but it's something so relevant or something that could be safely ignored?

我在这里没有看到这些信息,所以我问。

I've not seen this information around here, so I'm asking.

推荐答案

Eclipse警告您,您可能会公开您认为是私密的信息。合成访问器可以被恶意代码利用,如下所示。

Eclipse is warning you that you may be exposing information you think is private. Synthetic accessors can be exploited by malicious code as demonstrated below.

如果您的代码需要在安全的VM中运行,那么使用内部类可能是不明智的。如果您可以使用反射并拥有对所有内容的完全访问权限,则合成访问器不太可能产生可测量的差异。

If your code needs to run in a secure VM, it may be unwise to use inner classes. If you can use reflection and have full access to everything, synthetic accessors are unlikely to make a measurable difference.

例如,考虑这个类:

public class Foo {
  private Object baz = "Hello";
  private class Bar {
    private Bar() {
      System.out.println(baz);
    }
  }
}

<$ c的签名$ c> Foo 实际上是:

public class Foo extends java.lang.Object{
    public Foo();
    static java.lang.Object access$000(Foo);
}

访问$ 000 是自动生成让单独的类 Bar 访问 baz 并将标记为合成属性。生成的精确名称取决于实现。常规编译器不允许您针对此方法进行编译,但您可以使用ASM(或类似)生成自己的类,如下所示:

access$000 is generated automatically to let the separate class Bar access baz and will be marked with the Synthetic attribute. The precise names generated are implementation dependent. Regular compilers won't let you compile against this method, but you can generate your own classes using ASM (or similar) like this:

import org.objectweb.asm.*;
public class FooSpyMaker implements Opcodes {
  public static byte[] dump() throws Exception {
    ClassWriter cw = new ClassWriter(0);
    cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, "Spy", null, "java/lang/Object",null);
    MethodVisitor ctor = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
    ctor.visitCode();
    ctor.visitVarInsn(ALOAD, 0);
    ctor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
    ctor.visitInsn(RETURN);
    ctor.visitMaxs(1, 1);
    ctor.visitEnd();
    MethodVisitor getBaz = cw.visitMethod(ACC_PUBLIC, "getBaz",
        "(LFoo;)Ljava/lang/Object;", null, null);
    getBaz.visitCode();
    getBaz.visitVarInsn(ALOAD, 1);
    getBaz.visitMethodInsn(INVOKESTATIC, "Foo", "access$000",
        "(LFoo;)Ljava/lang/Object;");
    getBaz.visitInsn(ARETURN);
    getBaz.visitMaxs(1, 2);
    getBaz.visitEnd();
    cw.visitEnd();
    return cw.toByteArray();
  }
}

这会创建一个名为间谍,允许你拨打访问$ 000

This creates a simple class called Spy that will allow you to call access$000:

public class Spy extends java.lang.Object{
    public Spy();
    public java.lang.Object getBaz(Foo);
}

使用此功能,您可以检查 baz的值没有反射或任何暴露它的方法。

Using this, you can inspect the value of baz without reflection or any method exposing it.

public class Test {
  public static void main(String[] args) {
    Foo foo = new Foo();
    Spy spy = new Spy();
    System.out.println(spy.getBaz(foo));
  }
}

间谍实现要求它与 Foo 在同一个包中,并且 Foo 不在< a href =http://download.oracle.com/javase/tutorial/deployment/jar/sealman.html\"rel =noreferrer>密封的JAR 。

The Spy implementation requires that it be in the same package as Foo and that Foo isn't in a sealed JAR.

这篇关于合成方法的惩罚是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆