Having a difficult time making a static method which utilizes non-static methods

那年仲夏 提交于 2019-12-13 03:17:05

问题


I'm about 6 weeks into learning Java and still struggling with implementing static methods (thought I really understood it, but this proved me wrong!).

I'm trying to make the value of a locally stored key-value pair available publicly. Here's my initial code:

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

Of course, I get an error "Cannot make a static reference to the non-static method getSharedPreferences(String, int) from the type ContextWrapper", so I try to wrap the non-static method in my own public method, as a similar StackOverflow answer indicated:

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

But this just caused the same error as I haven't resolved the call to the non-static getSharedPreferences method. What's the best way to resolve this? Is it to create a class that wraps getSharedPreferences instead?

Thanks for your patience while I struggle with static nomenclature.


回答1:


If you want to write a static method that utilizes non-static methods, you just pass an instance to it like this:

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

So what you're doing is a great pattern. I use it all the time for "helpers" that can be reused across many classes (aka composition) Just make your "SomeObject" the Context.

Here's the pattern I use in Android to get a nice central point to define default preferences:

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

...

This pattern allows the definition of default values to be in one place.




回答2:


I think you might be misunderstanding how static works.

A static method (or variable) is one that has a single copy for all instances of the class and does not require and instance of the class to invoke it. For example,

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

That can be invoked as

MyClass.sayHello();

Notice there is no new instance of MyClass created.

An instance method is one that requires a particular instance of a class and usually relies on some internal state of the class.

class MyClass {

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

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

Now you would need a specific instance of the class

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

A static method cannot reference an instance method (or instance variable) because a static method is not tied to a particular instance of a class.

Non-static methods can access both non-static and static methods.

In general, if a method relies on state of the instance, it should be a non-static method. If it does not rely on internal state of the instance, then it can be a static method.

In your case, getSharedPref does not access any state from the instance of Settings, so it can be made into a static method and can then be accessed by other static methods in the class.




回答3:


You can't access a non-static method from inside of a static method. what you are doing here is the same thing. You are accessing a non-static method, namely, getSharedPref() from inside of a static method getDriverNum




回答4:


Simply, you need to know two things:

  1. you can call static methods in non-static methods

  2. you cannot call non-static methods in static methods in the same class (except you new a instance of another class, and call non-static methods by that objects)

that's why you get error, you break the second rule when you callgetSharedPref() in getDriverNum().

To solve this, try to make getSharedPref() static, and in return make getSharedPreferences() static.




回答5:


In your Helper class, just pass it the static variable of the Activity class. e.g.

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);
   ...
   }


来源:https://stackoverflow.com/questions/11321853/having-a-difficult-time-making-a-static-method-which-utilizes-non-static-methods

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!