制作一个利用非静态方法的静态方法很困难

时间:2012-07-04 02:55:19

标签: java android instantiation static

我大约需要6周时间学习Java并且仍在努力实现静态方法(我以为我真的理解它,但这证明我错了!)。

我正试图公开提供本地存储的键值对的值。这是我的初始代码:

public class Settings extends Activity implements OnClickListener {
        public Settings(TextView loginText, TextView passwdText) {
    super();
    this.loginText = loginText;
    this.passwdText = passwdText;
}

public static String getDriverNum() {
    SharedPreferences sp = getSharedPreferences(DELEX_SP, MODE_PRIVATE); <---ERROR
    String Login = sp.getString("KeyLgn", "No Login Found");
    return Login;
}

当然,我得到一个错误“无法从ContextWrapper类型中对非静态方法getSharedPreferences(String,int)进行静态引用”,所以我尝试将非静态方法包装在我自己的公共方法中,作为类似的StackOverflow answer表示:

public class Settings extends Activity implements OnClickListener {
public Settings(TextView loginText, TextView passwdText) {
    super();
    this.loginText = loginText;
    this.passwdText = passwdText;
}

public static String getDriverNum() {
    String Login = getSharedPref().getString("KeyLgn", "No Login Found"); <-- SAME ERROR
    return Login;
}

public  SharedPreferences getSharedPref() {
    SharedPreferences sp = getSharedPreferences(DELEX_SP, MODE_PRIVATE);
    return sp;
}

但这只是导致了同样的错误,因为我没有解决对非静态 getSharedPreferences 方法的调用。解决这个问题的最佳方法是什么?是创建一个包装 getSharedPreferences 的类吗?

感谢您在我与静态命名法斗争时的耐心。

5 个答案:

答案 0 :(得分:3)

我认为你可能会误解静态是如何运作的。

静态方法(或变量)是对该类的所有实例都具有单个副本的方法,并且不需要该类的实例来调用它。例如,

class MyClass {
      public static void sayHello() {
          System.out.println("hello");
      }
 }

可以调用

MyClass.sayHello();

请注意,没有创建MyClass的新实例。

实例方法是需要类的特定实例并且通常依赖于类的某个内部状态的方法。

class MyClass {

    // assume this is initialized somewhere in the constructor
    private final String myName;

    public void sayMyName() {
        System.out.println(myName);
    }
}

现在你需要一个特定的类实例

MyClass m = new MyClass("Bill");
m.sayMyName();

静态方法不能引用实例方法(或实例变量),因为静态方法不依赖于类的特定实例。

非静态方法可以访问非静态方法和静态方法。

通常,如果方法依赖于实例的状态,则它应该是非静态方法。如果它不依赖于实例的内部状态,那么它可以是静态方法。

在您的情况下,getSharedPref不会访问Settings实例中的任何状态,因此可以将其设置为静态方法,然后可以通过类中的其他静态方法访问。 / p>

答案 1 :(得分:0)

如果您想编写一个使用非静态方法的静态方法,您只需将实例传递给它:

public static void invokeMethod(SomeObject foo) {
    foo.bar();
}

所以你正在做的是一个伟大的模式。我一直用它来帮助那些可以在许多类中重用的“助手”(也就是组合)只是让你的“SomeObject”成为上下文。

这是我在Android中使用的模式,以获得定义默认首选项的一个很好的中心点:

import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;

import java.util.HashMap;
/**
 * Provides support functions for getting preferences as well as a
 * central place for storing default preferences.
 */
public final class PreferencesHelper {
    public static class Preferences {
        public static final String SOME_SETTING = "SOME_SETTING";
    }

   /** This allows us to define our default preferences all in one place */
    private static HashMap<String, Object> sDefaultPreferences =
        new HashMap<String, Object>(){{
        put(Preferences.SOME_SETTING, "value");
    }};

    public static SharedPreferences getDefaultPreferences(Context context) {
        return PreferenceManager.getDefaultSharedPreferences(context);
    }

    public static String getString(SharedPreferences prefs, String key) {
        return prefs.getString(key, (String) sDefaultPreferences.get(key));
    }

    /* Convenience method (use when getting only one preference) */
    public static String getString(Context context, String scanner) {
        SharedPreferences prefs = getDefaultPreferences(context);
        return getString(prefs, scanner);
    }

...

此模式允许将默认值的定义放在一个位置。

答案 2 :(得分:0)

您无法从静态方法内部访问static 方法。你在这里做的是同样的事情。您正在访问非static方法,即getSharedPref()来自静态方法getDriverNum

答案 3 :(得分:0)

简单地说,您需要了解两件事:

  1. 您可以在非静态方法中调用静态方法

  2. 你不能在同一个类中的静态方法中调用非静态方法(除了你新建另一个类的实例,并通过该对象调用非静态方法)

  3. 这就是您收到错误的原因,当您在getSharedPref()中致电getDriverNum()时,您违反了第二条规则。

    要解决此问题,请尝试将getSharedPref()设为静态,然后将getSharedPreferences()设为静态。

答案 4 :(得分:0)

在您的Helper类中,只需将Activity类的静态变量传递给它即可。例如

HelperClass:

public static int getDefaultYear()
{
    return HomeActivity.prefs.getInt("myYear", 10);
}

HomeActivity:

public class HomeActivity extends AppCompatActivity {

public static SharedPreferences prefs;

@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   prefs = this.getSharedPreferences(getString(R.string.applicationIdString), Context.MODE_PRIVATE);
   ...
   }