简体   繁体   中英

Why an object marked as final can be modified and call non-final method in Java?

I am new to Java and I am from C++ background.

I thought final in Java works just like const in C++ but I guess not.

Object initiated as const in C++, only can call const methods and cannot change fields in the object.

But in my code below, I am able to assign value in pet . ie pet.id = new ObjectId(newPetId); .

private void addPet() {
    progressBar.setVisibility(View.VISIBLE);

    final Pet pet;

    try {
        // Locally add and save pet.
        pet = getPetFromUserInput();

    } catch (InvalidInputException e) {
        progressBar.setVisibility(View.GONE);
        return;
    }

    pet.id = new ObjectId(); // Modify field member directly.
    pet.updateName("MyPet"); // Call non-final method.
}

Referencing Erik's answer in comments, I found an easy explanation for C++ programmers.

Pet pet; in Java is like Pet* pet; in C++.

final Pet pet; in Java is like Pet * const pet; in C++ which makes the pointer const but not the value itself.

Note that there is a subtle difference in Java and C++.

In C++, you have to assign a value when declaring a const variable but in Java, it lets you do it later but only once.

In Java, the keyword "final" simply means that once initialized, you cannot change the value of the variable. for example,

final int x = 0;`
//You can't do this!!!
int x=5

It has nothing to do with that variable calling methods.

In java "final" means this

1.If you use "final" before a class, then it means there is no chance to create subclass to that class.

public final class Person {
void getName() {

}

}

Then you can't create like this.

public class Man extends Person{
}
"The type Man cannot subclass the final class Person" will be shown
  1. If you write "final" before a method then

     public class Person { final void getName() { } } 

Then you can create subclass to this Person class but you cant override the getName() in subclass.

public class Man extends Person{

@Override
void getName() {
    // TODO Auto-generated method stub
    super.getName();
}

}

"Cannot override the final method from Person" will be shown.
  1. If you write "final" before a variable in a class, then you can't alter the value of that variable

exammple:

public  class Person {
public final String name;
void getName() {

}   
}

then in subclass, you can't modify the value.

public class Man extends Person{

public void getName() {
    name = "child";
}

}
"The final field Person.name cannot be assigned" will be shown

all these will shown in compile time itself.

Hope this helps you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM