web-dev-qa-db-ja.com

一時的なキーワードはメソッドをマークできますか?

JavaクラスJava.util.Localeで、キーワードtransientがメソッドをマークしていることがわかりました。

 public final class Locale
    implements Cloneable, Serializable
{
    private static class LocaleNameGetter
        implements Sun.util.LocaleServiceProviderPool.LocalizedObjectGetter
    {

        public transient String getObject(LocaleNameProvider localenameprovider, Locale locale, String s, Object aobj[])
        {
            if(!$assertionsDisabled && aobj.length != 2)
                throw new AssertionError();
            int i = ((Integer)aobj[0]).intValue();
            String s1 = (String)aobj[1];
            switch(i)
            {
            case 0: // '\0'
                return localenameprovider.getDisplayLanguage(s1, locale);

            case 1: // '\001'
                return localenameprovider.getDisplayCountry(s1, locale);

            case 2: // '\002'
                return localenameprovider.getDisplayVariant(s1, locale);
            }
            if(!$assertionsDisabled)
                throw new AssertionError();
            else
                return null;
        }

なぜこれができるのか誰かに教えてもらえますか?

24
Chuanshi Liu

いいえ、できません。フィールドに対してのみ有効です。逆コンパイルすることで、.classからソースを取得しているようです。これは逆コンパイラのバグです。Java.lang.reflect.Modifiersrcを見ると、transientvarargsの値が同じであることがわかります。

public static final int TRANSIENT        = 0x00000080;
...
static final int VARARGS   = 0x00000080;

フィールドの場合は0x00000080transientを意味し、メソッドの場合(あなたの場合)はvarargsを意味します。これは、Java.util.LocalesrcでのgetObjectの外観です。

public String getObject(LocaleNameProvider localeNameProvider,
                        Locale locale, 
                        String key,
                        Object... params) {   <-- varargs

.class(バイトコード)では、可変引数はObject []によって最後のパラメーター+修飾子ビット7 = 1(0x80)として表されます。デコンパイラーは古く、varargsを知らないだけだと思います。これは、Java 1.5なので、transientとして出力されます。

48

このコードが逆コンパイルされている場合は、次の結果である可能性があります。 なぜJava可変個引数が一時的として識別されるメソッド?

私はそこから引用しています:

ある種の答えは、javassistAccessFlagのコードにあります。

public static final int TRANSIENT = 0x0080; public static final int VARARGS = 0x0080;どちらも同じ値のようです。また、transientはメソッドには何の意味もありませんが、varargsはフィールドには何の意味もありませんので、同じでもかまいません。

6
Menios

transientはメンバー変数にのみ適用でき、メソッドには適用できないため、ここで問題が発生します。

コード内の変数名(String sObject[] abojなど)を見ると、このソースは関連する.classファイルを逆コンパイルして生成されたようです。

使用しているデコンパイラーに、メソッド宣言に誤ってtransisentが追加されているバグがあると思います。

3
Dave Webb

これはバグである必要があります。またはいくつかのバグのある改訂?トランジェントは変数にのみ適用されます。あなたがそれを見るところにリンクを提供できますか?

1
Eugene

Javaのドキュメントには、transientキーワードはインスタンス変数にのみ適用されると記載されているため、これは意味がありません。

1
Rubén