seekingStillness
seekingStillness

Reputation: 5093

Best solution for static member being accessed by instance reference

I have this method in nearly all my classes.

//listener - info
private void clickInfoListener(final ImageView iv, final int title, final int text){
    iv.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            materialHelper.showInfoDialog(MainActivity.this, iv, title, text);
        }
    });
}

Accessing this static method in a helper class

public static void showInfoDialog(Context context, final ImageView iv, final int title, final int text){
    iv.setImageResource(R.drawable.ic_info_touched);
    //
    AlertDialog.Builder builder = new AlertDialog.Builder(context);
    builder.setCancelable(true);
    builder.setTitle(title);
    builder.setMessage(text);
    builder.setPositiveButton(R.string.gotIt, null);
    builder.show();
    //
    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        public void run() {
            iv.setImageResource(R.drawable.ic_info_primary);
        }
    }, 25);
}

I am getting lint warning of "static member being accessed by instance reference". I don't know how to not use "this" here. So I have two options.

1) Ignore the lint warning

2) Drop the "static" in my helper method.

Which is better? Or propose a third solution.

Upvotes: 5

Views: 16096

Answers (4)

Michael  Nicholson
Michael Nicholson

Reputation: 91

use with:

import static com.yourcompany.yourproject.materialHelper.showInfoDialog;

Upvotes: 2

Vyacheslav
Vyacheslav

Reputation: 27221

E.g. , assume

    public static YourClass {
//.. the other code
    private void clickInfoListener(final ImageView iv, final int title, final int text){
        iv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                materialHelper.showInfoDialog(MainActivity.this, iv, title, text);
            }
        });
    }

    public static void showInfoDialog(Context context, final ImageView iv, final int title, final int text){
        iv.setImageResource(R.drawable.ic_info_touched);
        //
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setCancelable(true);
        builder.setTitle(title);
        builder.setMessage(text);
        builder.setPositiveButton(R.string.gotIt, null);
        builder.show();
        //
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            public void run() {
                iv.setImageResource(R.drawable.ic_info_primary);
            }
        }, 25);
    }
    }


//somewhere
YourClass materialHelper = new YourClass();

So.

this method showInfoDialog(MainActivity.this, iv, title, text); is 'static method'

It means: this method is shared for all instances of this class (static variable too). It really doesn't matter where it was called. That's why lint says: "oh gosh, why do you call this static method using this instance? It might change shared values in the other instances! Be careful!". Java will understand your code but this is a small mistake (your misunderstooding). That's why the correct solution is to use this:

YourClass.showInfoDialog(MainActivity.this, iv, title, text);

Upvotes: 3

KarelPeeters
KarelPeeters

Reputation: 1465

The warning is saying that you're calling a static method showInfoDialog through an instance materialHelper instead of through the class MaterialHelper itself. This is "bad" because it suggests the method is actually an instance method that depends on some state in the instance.

The solution is to replace

materialHelper.showInfoDialog(...)

everywhere in your code with

MaterialHelper.showInfoDialog(...)

Upvotes: 13

CommonsWare
CommonsWare

Reputation: 1006869

Or propose a third solution.

Replace materialHelper with the class name where showInfoDialog() resides. From your description, materialHelper is an instance of this class.

Upvotes: 4

Related Questions