【问题标题】:Can transient keywords mark a method?瞬态关键字可以标记方法吗?
【发布时间】:2013-04-20 11:29:09
【问题描述】:

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

谁能告诉我为什么会这样?

【问题讨论】:

  • @user85121 你能提供你看到的链接吗?
  • 我检查了 jdk 1.6 源,它没有 transient 关键字
  • @user85121,你有什么版本的jdk?这是一个重要的问题,以便检查特定来源中发生了什么。如果这段代码是反编译器的结果,作者应该提到这一点!
  • 作者好像消失了……:(

标签: java transient


【解决方案1】:
public class Result<T> implements Serializable {
    private static final long serialVersionUID = 1L;
    private Boolean  succ;
    private String code;
    private String msg;
    protected T data;

    public Result() {
    }

    public Result(Boolean succ) {
        this.succ = succ;
    }

    
    


    //Can use this here
    @Transient
    public boolean isFail(){
        return !isSucc();
    }
    public boolean isSucc() {
        return succ != null && succ;
    }
}

【讨论】:

  • 虽然此代码可能会解决问题,including an explanation 关于如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的回答添加解释并说明适用的限制和假设。
  • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
【解决方案2】:

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

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

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

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

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

【讨论】:

    【解决方案3】:

    如果这段代码已经被反编译,很可能是这样的结果:Why Java methods with varargs identified as transient?

    我从那里引用:

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

    public static final int TRANSIENT = 0x0080;公共静态最终整数 VARARGS = 0x0080;看起来两者具有相同的值。而且因为 瞬态对方法没有任何意义,而可变参数对方法没有任何意义 字段,相同就可以了。

    【讨论】:

      【解决方案4】:

      transient只能用于成员变量,不能用于方法,所以这里有问题。

      查看代码中的变量名称——例如String sObject[] aboj——看起来这个源代码是通过反编译相关的.class 文件生成的。

      我认为您使用的任何反编译器都有一个错误,错误地将transisent 添加到方法声明中。

      【讨论】:

        【解决方案5】:

        Java 文档指出瞬态关键字仅适用于实例变量,因此这没有任何意义

        【讨论】:

          【解决方案6】:

          这一定是一个错误。还是一些错误的修订?瞬态仅适用于变量。你能提供一个你看到的链接吗?

          【讨论】:

            猜你喜欢
            • 2015-04-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-11-20
            • 2012-07-05
            • 2013-08-04
            • 2010-10-28
            • 1970-01-01
            相关资源
            最近更新 更多