瞬态关键字可以标记方法吗?

2022-09-01 16:45:43

在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;
        }

有人能告诉我为什么会这样吗?


答案 1

不,它不能,它只对字段有效。您似乎通过反编译从.class中获取源代码。这是反编译器错误,如果你看一下src,你会看到它并具有相同的值java.lang.reflect.Modifiertransientvarargs

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

对于字段表示,对于方法(您的情况)它表示 。这就是java.util.Locale src中的样子0x00000080transientvarargsgetObject

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

在.class(字节码)中,varargs由 Object[] 表示为最后一个参数 + 修饰符位 7 = 1 (0x80)。我猜反编译器是旧的,根本不知道哪个是从Java 1.5开始的,所以它把它打印为.varargstransient


答案 2

如果这段代码被反编译了,那很可能是这样的结果:为什么Java方法的varargs被标识为瞬态的?

我从那里引用:

可以在javassist AccessFlag的代码中找到答案

公共静态最终 int TRANSIENT = 0x0080;公共静态最终 int VARARGS = 0x0080;两者似乎具有相同的值。由于瞬态对方法没有任何意义,而varargs对字段没有任何意义,因此它们可以相同。


推荐