I have trouble understanding why double xx and yy are put final in the constructor. Why don't I just put them double xx and double yy. Why
do they have to be final? I guess the whole purpose of this is
creating an immutable object.
public class Point {
private final double x, y;
private double distance;
public Point(final double xx, final double yy) {
this.x = xx;
this.y = yy;
this.distance = -1;
}
}
There is no need for these parameters to be final.
There are two reasons to make parameters final:
To make use of them in an inner class declared in that function;
To prevent their values from being changed accidentally.
Clearly (1) doesn't apply.
(2) isn't necessary because it's such simple code, and you can see that it's not changing the parameters.
There is a school of thought which says that all parameters and local variables should be declared final as a matter of course, as it makes it easier to reason about the code, in the same way that using immutable types makes it easier to reason about code using them.
There is another school of thought which says that adding final everywhere is just unnecessary noise, and, if you are writing methods where you can't tell if the value is changing, your methods are too long.
Largely, making parameters and local variables final comes down to personal/team preference.
Declaring x and y variables as final solves the purpose (i.e. The value must not be changed later). There is no point in declaring the constructor's parameters as final.
Related
public class Point {
private double x;
private double y;
Point (double x, double y)
{ this.x = x; this.y = y; }
double getX() { return x; }
double getY() { return y; } }
Are the objects in the above class immutable? Explain.
I am getting confused because
There r no setters so nothing can modify the objects
BUT
there is no final variable or final class which it should contain.
If the class gets extended, it could add extra fields that are not immutable, or the methods could be overridden to return a different value each time. Doesnt this make the class not immutable?
If the class gets extended, ... the methods could be overridden to return a different value each time. Doesn't this make the class not immutable?
Your question is subtle. If some class MutPoint extends Point and overrides the getX() and getY() methods to return non-constant values, that doesn't change the Point class itself. Instances of Point sill will be effectively immutable, but a caller would be allowed to pass MutPoint objects to your methods that expect Point arguments. What happens then? Depends on how you write your code. It could be that your code would behave badly if the caller gave you a Point-like object, and then subsequently changed its "value".
If your code that uses Point objects requires them to never change, then you might want to declare the whole class final
public final class Point { ... }
That way, your client will not be allowed to override the class, and will not be allowed to call your methods with anything other than an actual Point instance.
Yes, they are immutable. You can read about it here
http://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html
Yes, because you can't accsess to the data member and you don't have method that change your data members
I am an AP java student and while working on a project I wondered if it is a good practice to have a parameter that is a global variable. If you're wondering why I would want to do that well is so I wouldn't have to do this:
public class Circle {
private DrawingTool pen;
private SketchPad paper;
private double myX;
private double myY;
private double myWidth;
private double myHeight;
public Circle(double x, double y, double width, double height){
paper = new SketchPad(500,500);
pen = new DrawingTool(paper);
x = myX; //I don't want to have to assign this every time
y = myY; //like here
width = myWidth; // and here
height = myHeight; // and here
}
}
is it allowed to just do the following:
public Circle(double myX, double myY, double myWidth, double myHeight){
paper = new SketchPad(500,500);
pen = new DrawingTool(paper);
}
}
and every time I pass the arguments to the parameter they will automatically be assigned to the global variables?
and every time I pass the arguments to the parameter they will automatically be assigned to the global variables?
No. There's nothing within Java which will make the "parameter to instance variable" (which isn't really "global") assignment automatic. Many IDEs have the ability to generate the code for you, but it does need to be there.
An object stores its state in fields (variables in some programming languages) and exposes its behavior through methods (functions in some programming languages). Methods operate on an object's internal state and serve as the primary mechanism for object-to-object communication. Hiding internal state and requiring all interaction to be performed through an object's methods is known as data encapsulation — a fundamental principle of object-oriented programming.
Source: What Is an Object?
I am learning Java right now and I am stumped on constants. It says in my book that they are good for declaring a variable that doesn't change. Example would be:
final double PI = 3.14159
How is this different from
double pi = 3.14159
How would "pi" change in a program?
The final keyword makes a variable unchangeable. This means that you can initialize it and you will never be able to change it.
final double PI = 3.14159
PI = 2; //You are trying to change the value of a constant, this will result in a compile-time error
To change a variable's value, just re-assign a value to that variable:
double pi = 3.14159;
pi = 2; //pi is not a constant, so its value can be changed
You sure can define pi as a standard double. In fact, if you're defining PI then it needs to be a double (or BigDecimal depending on your use).
The final keyword means this value will not change. It makes your code far more readable. Look at it like this:
final double PI = 3.14;
double a = Math.pow(PI * radius, 2);
You see how it's instantly obvious PI is the value you're using, as opposed to just 3.14 which can mean anything in any context?
Read langugage spec jls #4.12.4
A variable can be declared final. A final variable may only be assigned to once. Declaring a variable final can serve as useful documentation that its value will not change and can help avoid programming errors.
The reason to declare a constant is to ensure that it cannot be changed. If in your code, you attempt to change its value, you'll get an error (I think, bit rusty on Java, to be honest)
While, off the top of my head, I can't think of a situation where a constant couldn't be declared as a variable, it makes the code clearer and prevents you or another coder from accidentally changing a value that shouldn't be changed.
final means that value of variable can't be changed.
So the following code will not be accepted:
final double PI = 3.14159;
PI = 3.14; //error because PI is declared as final
final double PI = 3.14159
PI = 2; // Compile error
double pi = 3.14159
pi = 2; // Works fine
Final fields cannot be modified after they are initialized. They are initialized when the constructor is called, and keep their value for the rest of the object's lifecycle.
The point of making it a constant, is so you or an other programmer don't change the value in error. It's not can Pi change it's declaring to the compiler/interpreter that any any attempt to change it, is unacceptable.
once you discovered anonymous inner class or method implementation\overriding you will realize what your final variables are good for.
The basic means of final is to ensure the reference of the object won't change after object construction.
You can do something like this:
public class PI {
private double piValue;
public PI(double pi) {
this.piValue = pi;
}
public double getPi() { return piValue; }
public void setPi(double newPi) { piValue = newPi; }
}
//somewhere else
final PI myPi = new PI(3.14159);
//but you can change it via setter;
myPi.setPi(3.13);
//but myPi reference wont change!!!
public class NotActuallyImmutable {
private final int x;
public NotActuallyImmutable(int x) {
this.x = x;// line 1
}
public int getX() {
return x;
}
}
public class Mutable extends NotActuallyImmutable {
private int x = 123;
public Mutable(int x) {
super(x);
}
public int getX() {
return x++;
}
}
now in my main class
NotActuallyImmutable n = new Mutable(42); // line2
int x = n.getX();
System.out.println("x is"+x);
I am expecting the output as 42 but it return the output as 123. I am expecting 42 because at line 2 I am making object of class Mutable and then at line 1 I am setting value as 42. so when i do n.getX() I should get the this latest value not the default 123. I know Ii am missing something but not able to figure out the logic behind it?
The problem is that the field x in Mutable and the field x in class NotActuallyImmutable are not the same. The x that is returned by getX() is the one in Mutable (because the getX() that is invoked is Mutable.getX(), not NotActuallyImmutable.getX()).
Note that if you removed the instance field from Mutable, then you would have a compiler error because NotActuallyImmutable.x is private to NotActuallyImmutable and not accessible to any code in Mutable.
If you made NotActuallyImmutable.x a protected field, then Mutable.x would shadow it and you would still have the same behavior. If you removed Mutable.x in this case, you would still have a compiler error because you were trying to increment a final field.
If you remove Mutable.getX(), then the x that would be returned by getX() would be NotActuallyImmutable.x, despite there being another field of the same name in Mutable.
The private int x in Mutable and the private int x in NotActuallyImmutable are completely different fields that just have the same name.
This isn't a problem for the compiler because you can't access a private field from another class. So as far as the compiler is concerned, when you define Mutable, the x in NotActuallyImmutable is invisible and might as well not exist.
It is of course confusing for the programmer. If you rename one of the fields to y (and the getter method to getY) the behaviour seems much more intuitive.
NotActuallyImmutable n = new Mutable(42); // line2
This means you have an object of type NotActuallyImmutable but the instance of created object is Mutable.
so in this code your dealing with Mutable object which will return 123. as the number you passed is saved in NotActuallyImmutable not in Mutable,
n has two different x values which are visible in different contexts, the parent class's private member variable and the child class's private member variable.
NotActuallyImmutable n = new Mutable(42); // line2
Creates a new Mutable. Executes parent(x) which sets the parent class's x to 42.
int x = n.getX();
n is a Mutable instance so this calls Mutable's getX() which returns Mutable's value for x (123) rather than the parent's.
I agree with Nice explanations given in above answers. But to to just brief the final understanding. As i am doing new Mutable(42).getX(), jvm first will look in Mutable object to get the value of X not inside NotActuallyImmutable. If i remove getX() method from Mutable , i get the expected(as per my expectation) value i.e 42.
This example gets messy becoz variable name i.e X is same in parent and child class but good for understanding concept
I am trying to access a private final static double from another class.
Here is the class:
public class coolMath{
private final static double alpha = 5.87;
public coolMath(){
}
public static double calDistance(double x1, double y1, double x2, double y2){
double dist = Math.sqrt(Math.pow((x2-x1), 2) + Math.pow((y2-y1),2));
return dist;
}
}
I need to access the variable alpha in another class. Is this possible? Does something need to happen in the constructor to make it available? Any ideas?
Either make alpha a public field or provide a public static double getAlpha() that returns it.
If you make the field public, you access it like so double a = coolMath.alpha.
Otherwise, double a = coolMath.getAlpha();
I strongly suggest you go through java modifiers again.
This could technically be possible through some esoteric reflection methods, but I highly discourage it. It's better to change the visibility of your alpha variable or write some method that returns it (or perhaps sets it, if you need that also (but not if your var is final)).