2

Why would you ever need a final variable in a non-static context? Does the compiler automatically assign static to all final variables?

Edit: I know the difference between static and final, what I am asking is whether there is any case when you would need final int x instead of static final int x. Why would you need a copy of x in each instance when you cannot modify it?

  • Why wouldn't you need it? – Bubletan Jun 28 '17 at 13:21
  • 5
    If you want a member to be unchangeable, but set to different values upon initialization of an object, you make it final. Static means it's the same for all objects of that class. – Mrl0330 Jun 28 '17 at 13:22
  • https://stackoverflow.com/questions/13772827/difference-between-static-and-final – Artyom Jun 28 '17 at 13:22
  • 1
    Possible duplicate of [Difference between Static and final?](https://stackoverflow.com/questions/13772827/difference-between-static-and-final) – byxor Jun 28 '17 at 13:24
  • 2
    The most common use of a *non static* final is an instance variable that is set from a parameter of the constructor. Its value is different for each instance, but it is not changed after the instance is created. – RealSkeptic Jun 28 '17 at 13:25
  • 1
    The amount of answers on this question is astonishing. A simple explanation on the difference between `static` and `final` is all that's required, and has been answered before. – byxor Jun 28 '17 at 13:30
  • Yes! @RealSkeptic this is what I am asking, the other answers are missing the point! Could you please elaborate some more? –  Jun 28 '17 at 13:34
  • 1
    One reason to declare a variable as final and not static is if you want to access it in an anonymous class (which is a quite common thing in many frameworks). See: [Why are only final variables accessible in anonymous class?](https://stackoverflow.com/questions/4732544/why-are-only-final-variables-accessible-in-anonymous-class) – OH GOD SPIDERS Jun 28 '17 at 13:43
  • You declare a local variable or method parameter final so its value won't change within the block. You declare an instance variable final so its value won't change within that instance, but it can differ for other instances. You declare an instance method final so it can't be overridden. Simple. – Lew Bloch Jun 28 '17 at 14:11

5 Answers5

3

Keyword final is used when you want to allow to assign value only once at construction time.

public class Person {
    public final String name;

    public Person(String name) {
        this.name = name;
    }
}

Person p = new Person("a");
p.name = "newName"; // COMPILE ERROR name is marked as "final" thus can not be changed.

when you would need final int x instead of static final int x?

Consider these classes:

public class OriginConstants {
      // static final fields allows to access constants via class accessor i. e. OriginConstants.x (no need to create instance)
      public static final int x = 0;
      public static final int y = 0;
}

public class ImmutablePoint {
    public final int x;
    public final int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

public class MutablePoint {
    public int x;
    public int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

Examples of usage

// create immutable point shifted from coordinate system origin by 5
ImmutablePoint ip = new ImmutablePoint(OriginConstants.x + 5, OriginConstants.y + 5);

// updating point coordinate by 10
ip.x += 10; // COMPILE ERROR 
ip.y += 10; // COMPILE ERROR

// we cannot modify final fields, but we can create new instance with shifted coordinates
ImmutablePoint shiftedIp = new ImmutablePoint(ip.x + 10, ip.y + 10);

// create mutable point shifted from coordinate system origin by 5
MutablePoint mp = new MutablePoint(OriginConstants.x + 5, OriginConstants.y + 5);

// updating point coordinate by 10
ip.x += 10; // OK
ip.y += 10; // OK

I would use immutable points for some coordinates that can not be changed in time. Suppose, we have canvas with height = 100, width = 100. We can create helper constant points as follows:

public class Canvas {
    public static final int HEIGHT = 100;
    public static final int WIDTH = 100;

    // anchor points
    public static final ImmutablePoint topLeft = new ImmutablePoint(0,0);
    public static final ImmutablePoint topRight = new ImmutablePoint(Canvas.WIDTH, 0);
    public static final ImmutablePoint bottomLeft = new ImmutablePoint(0, Canvas.HEIGHT);
    public static final ImmutablePoint bottomRight = new ImmutablePoint(Canvas.WIDTH, Canavas.HEIGHT);
}

This way we can be sure, that topLeft is always 0,0 and can not be changed by some mistake.

matoni
  • 2,479
  • 21
  • 39
  • Great! Your edit is exactly what I was asking! I was trying to think of a case where such declarations would not behave identically. Your Constructor initialization is exactly that! Thanks! –  Jun 28 '17 at 14:01
2

An important usage of final variables is in immutable objects. Immutable objects are objects with are created and initialized once an then never mutated. You can have many instances of such objects, so static fields don't make sense. But since these objects are immutable, it is mandatory to make all fields final.

Example for a simple immutable class:

class User {
  private final String name;

  public User(String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }
}
Florian Fankhauser
  • 3,615
  • 2
  • 26
  • 30
  • 1
    `final` does not guarantee that class instances are immutable, what if the field is `final`, but has assigned object which state can be changed? – matoni Jun 28 '17 at 13:39
1

Because it makes a lot of sense to make fields of classes final.

Actually, that should be your default to do. You only drop the final keyword on your fields if you have good reasons to later change their values.

Reasoning is simple: you want the compiler to tell you when you forgot to initialize your fields. Beyond that: you initialize your fields even right there, or within the constructor. Because then you can be sure in all other code, that all fields are correctly initialized.

In other words: you want to do some research why immutability is regarded as a positive property of classes!

GhostCat
  • 137,827
  • 25
  • 176
  • 248
0

static means you don't have to have an instance of a class to use the variable.

For example Math.PI, you don't need to instantiate Math class to use the value of PI, for this reason it is static. It has to be constant and so it is also final also.

If you don't have final only, it means variable is supposed to be a constant for that instance. Once class is initialized, it is final and cannot be changed. Add static if you want the constant to be used without having to instantiate the class.

SomeDude
  • 13,876
  • 5
  • 21
  • 44
0

This is done to prevent having methods modify state in an instance of an object. They are called immutable objects and generally simplify your programming, as they will simplify your test scenarios.

This was well answered here: What is meant by immutable?

In your example, you would do something like this:

public class Person {
    public final String name;

    public Person(String name) {
        this.name = name;
    }
    public Person rename(String name) {
        return new Person(name)
    }

 }
JP Belanger
  • 119
  • 8