6

这可能是一个菜鸟问题,但我想知道为什么我们必须使用静态方法(makeText)来创建 Toast 而不是构造函数。

为什么我们必须使用这个:

makeText(Context context, CharSequence text, int duration)

而不是这个:

new Toast(Context context, CharSequence text, int duration) 

这是 makeText 方法:

    public static Toast makeText(Context context, CharSequence text, int duration) {
        Toast result = new Toast(context);

        LayoutInflater inflate = (LayoutInflater)
                context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View v = inflate.inflate(com.android.internal.R.layout.transient_notification, null);
        TextView tv = (TextView)v.findViewById(com.android.internal.R.id.message);
        tv.setText(text);

        result.mNextView = v;
        result.mDuration = duration;

        return result;
    }

为什么我们没有以下内容:

public Toast (Context context, CharSequence text, int duration) {
    this(context);

    LayoutInflater inflate = (LayoutInflater)
            context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View v = inflate.inflate(com.android.internal.R.layout.transient_notification, null);
    TextView tv = (TextView)v.findViewById(com.android.internal.R.id.message);
    tv.setText(text);

    this.mNextView = v;
    this.mDuration = duration;
}

我出于任何原因搜索了网络和源代码,但没有找到。

如果您有想法,请不要犹豫。

4

3 回答 3

6

这个问题基本上深入到我什么时候应该将方法设为静态。答案很简单——当你的方法有一个非常具体的任务并且不改变对象的状态时。

类似于实用方法的东西,比如 add(int a, int b),它只返回 a+b。如果我需要存储值 a+b 以供以后用于对象,静态方法是严格禁止的(您将无法在静态方法中存储非静态变量)。但是,如果我们正在处理一些独立于对象状态的动作,那么静态就是答案。

如果静态独立于对象的状态,我们为什么要优先考虑它?

  1. 内存静态方法将只有一个副本,与对象的实际数量无关。

  2. 可用性 - 即使您没有单个对象,方法也可用

当然,缺点是我们保留了一个方法的副本,即使我们根本不使用它(如果它是非静态的并且没有创建对象,我们会节省这个空间)。但这比上面提到的优点要轻。

作为我们这里讨论的方法(makeText),不需要保持状态以备后用,最好的方法是静态方法。

- 编辑 -

上面提到的答案对于我们何时应该使用静态以及何时使用非静态更为通用,让我具体介绍一下 Toast 类。

Toast 类为我们提供了 2 种创建 Toast 对象的方法(请参阅http://developer.android.com/reference/android/widget/Toast.html

  1. makeText(Context context, CharSequence text, int duration) 返回一个 Toast 对象,该对象分配了值。

  2. 正常方式,使用 new Toast(context) 创建一个对象,然后根据需要设置值。

如果你使用方法 1,你说的是 Toast.makeText(context, text, duration).show(); 我们完成了。我一直使用这种方法。

方法 2 仅用于特定情况,来自http://developer.android.com/guide/topics/ui/notifiers/toasts.html

除非您打算使用 setView(View) 定义布局,否则不要对 Toast 使用公共构造函数。如果您没有要使用的自定义布局,则必须使用 makeText(Context, int, int) 来创建 Toast。

@CFlex,如果我正确地回答了你的问题,我想你只是想知道为什么我们有 Toast.makeText(context, text, duration) 返回一个 Toast 对象,而构造函数可以完成同样的事情。

每当我看到类似 ClassName.getObject 返回类的对象时,我都会想到单例模式。好吧,在这种情况下,我们并不是在谈论单例,我想假设 makeText 总是返回相同的对象(以保存 N 个对象的创建),否则它只是 Android 团队开发的一个花哨的东西。

于 2012-07-30T09:17:23.857 回答
2

一条规则:问问自己“即使还没有构造任何对象,调用这个方法是否有意义?” 如果是这样,它肯定应该是静态的。

请记住,对象存在于内存中,它们是为某些工作而创建的。静态方法可用于类中的所有对象,无需创建对象即可使用它们。

所以没有理由创建一个对象 Toast 来访问该方法makeText,当您可以将它作为静态方法访问时(更优雅和紧凑)

于 2012-07-30T09:00:29.787 回答
1

据我所知:

那是因为我们不希望保存对象 toast 的实例,这将需要持续使用的内存量,直到被 GarbageCollector 清除。

并且它始终可以访问显示,因此您的应用程序不需要任何权限集。

于 2012-07-30T08:59:00.740 回答