what is the use of keyword final?

2019-03-25 14:58发布

In the below code if i remove the keyword final from EditText i am an getting error in the line (6) where i pass EditText object (et) to the intent...I have to knw the significance of final keyword here...

final EditText et=(EditText)findViewById(R.id.t);
        Button b=(Button)findViewById(R.id.b1);
        b.setOnClickListener(new Button.OnClickListener(){
            public void onClick(View v)<br>
            {
            Intent on=new Intent(Intent.ACTION_CALL,Uri.parse("tel:"+et.getText()));
            startActivity(on);
            }
        });

7条回答
戒情不戒烟
2楼-- · 2019-03-25 15:23

It is because you use closure here. It means that inner class uses the context of the inbounded one. To use it the variables should be declared final in order not to be changed.

See more here.

查看更多
做个烂人
3楼-- · 2019-03-25 15:28

Final essentially means that the variable et will not be reassigned at any point and will remain around. This means that inner classes, like your listener, can trust that it wont be reassigned by some other thread which could cause all kinds of trouble.

final can also be used to modify a method or class definition, that would mean that the method can't be overriden by a subclass, or that the class cannot be extended.

查看更多
Bombasti
4楼-- · 2019-03-25 15:43

Final makes the variable et only allowed to be assigned once. It also changes the scope of the variable and allows the function onClick visibility to et. Without the final, et is not visible within the function onClick.

查看更多
三岁会撩人
5楼-- · 2019-03-25 15:46

Here is a link which discusses the final keyword. According to the specification (section 4.12.4):

A variable can be declared final. A final variable may only be assigned to once. It is a compile time error if a final variable is assigned to unless it is definitely unassigned (§16) immediately prior to the assignment.

查看更多
The star\"
6楼-- · 2019-03-25 15:47

Read this article to understand the implementation details involved:

The reason for this restriction becomes apparent if we shed some light on how local classes are implemented. An anonymous local class can use local variables because the compiler automatically gives the class a private instance field to hold a copy of each local variable the class uses. The compiler also adds hidden parameters to each constructor to initialize these automatically created private fields. Thus, a local class does not actually access local variables, but merely its own private copies of them. The only way this can work correctly is if the local variables are declared final, so that they are guaranteed not to change. With this guarantee in place, the local class is assured that its internal copies of the variables accurately reflect the actual local variables.

EDIT:

Berlin Brown says: "I posted a decompiled version of an anonymous inner class. But to be honest, I still don't see why the compiler has to have that information. Even if the field is declared final, the field can still be null. I think this is one of those Java quirks, you have to declare that field final...because that is the way it is. There isn't a clear reason why"

The reason is to make sure that users realize that closures "close over" variables and not values. Let's suppose that there was no requirement of having final local variables. Then we could write code like:

public void doIt() {
    for(int i = 0; i < 3; ++i) {
        runnables.add(new Runnable() {
            @Override
            public void run() {
                System.out.println(i);
            }
        });
    }
    run(runnables); // run each runnable
}

What do you think would be the output? If you think it would be "0 1 2" you would be mistaken since the Runnable closes over the "variable" i and not the "value" of i at that point in time and hence the output would be "2 2 2". What can be done to achieve the expected behaviour here? Two solutions: either rely on the users to have an understanding of how closures work or somehow enforce it at the language level. And it is the second option with which the language designers have gone with.

public void doIt() {
    for(int i = 0; i < 3; ++i) {
        final int j = i; // notice the final local variable
        runnables.add(new Runnable() {
            @Override
            public void run() {
                System.out.println(j);
            }
        });
    }
    run(runnables);
}

JFTR, I'm not saying that the second option is "the" way to go, it's just that having local variables marked as final before being used in anonymous inner classes is a big deal breaker for me. Of course, YMMV. :-)

查看更多
相关推荐>>
7楼-- · 2019-03-25 15:47

The purpose of “final” keyword in JAVA can be defined in three level are Class, Method, variable

Java final variable: If you make any variable as final, you cannot change the value of final variable (It will be constant).

Java final method: If you make any method as final, you cannot override it.

Java final class: If you make any class as final, you cannot extend it.
查看更多
登录 后发表回答