Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Final vs Private textviews

simple maybe stupid question. I have a login activity which launches another activity, and here's the code:

public class LoginActivity extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.login);
    ActionBar actionBar = getActionBar();
    actionBar.hide();

    Button btnLogin = (Button) findViewById(R.id.btnLogin);
    final TextView tvUsername = (TextView) findViewById(R.id.tvUsername);
    final TextView tvPassword = (TextView) findViewById(R.id.tvPassword);

    btnLogin.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            if (tvUsername.getText().toString().length()<1) {
                Toast msg = Toast.makeText(LoginActivity.this, "Enter a Username", Toast.LENGTH_LONG);
                msg.setGravity(Gravity.TOP|Gravity.LEFT, 0, 70);
                msg.show();
                tvUsername.requestFocus();
            } else if (tvPassword.getText().toString().length()<1) {
                Toast msg = Toast.makeText(LoginActivity.this, "Enter a Password", Toast.LENGTH_LONG);
                msg.setGravity(Gravity.TOP|Gravity.LEFT, 0, 200);
                msg.show();
                tvPassword.requestFocus();
            } else {
                startActivity(new Intent(LoginActivity.this,CrewScheduleActivity.class));
                finish();
            }
        }
    });
    }
}

My question is about the textviews. Eclipse basically said i had to make them final in order to use them in the onClick event of the button. NP so i did that and it worked.

The question is What is the difference between putting these above the @Override as private vs inside the OnCreate as final?

like image 950
user1848850 Avatar asked Nov 24 '12 03:11

user1848850


2 Answers

This has to do with closure in Java. Basically, when you use an anonymous class, the values (not objects themselves) used within it are copied to that class for usage. Therefore, it does not make sense to return or modify those variables within the class, hence they must be final.

However, if the variable is instead part of the class containing the anonymous class, that's different. Basically, your inner class has a reference to the LoginActivity object (as LoginActivity.this), and can use and modify its members and methods.

When you put them "above the @Override", you are making them member variables of the LoginActivity class. Therefore, they can be accessed by the anonymous class.

Succinctly, the difference is that: final variables are local to the method, and copied to the anonymous class; member variables are local to the containing class and are modified by the anonymous class.

If you want to reuse the data from the anonymous class later, use a member variable. If you only need it within onCreate() and the anonymous class, then a final variable will suffice.

like image 123
Cat Avatar answered Oct 18 '22 23:10

Cat


When you declare the TextView field (or any field for that matter) as public, it can be accessed directly by any other class, which I don't believe is your intention; there's no reason to make the TextView variable public.
If it is set as private, there is a guarantee that its value won't be overridden in another class, which is what the final keyword was designed to do in the first place. So, simply set it as private, and you won't have to worry about Eclipse correcting you.
So, in summary: making the field private/final ensures that the value cannot be overridden from another class, which is a good design.

Hope this rambling helps. I'll be glad to clarify it better if it doesn't.

like image 28
Kneel-Before-ZOD Avatar answered Oct 18 '22 22:10

Kneel-Before-ZOD