I have two fields in java class, both are Integers:
int a = 0;
int b = a * a;
Once the field a receives another value, 10, for example. But it hasn't any influence on field b, this field remains 0 instead of 100.
How to do it best in 'java' style?
You also have to assign a value to b. You should make a and b private, and provide getters for both plus a setter for a that also updates b like this:
int getA() {
return a;
}
int getB() {
return b;
}
void setA(int a) {
this.a = a;
this.b = a*a;
}
Each field is an independent variable and reading it normally returns the value last written to it (*).
In order to implement the behavior you require you should make b a method:
public class X {
int a = 0;
int b() {
return a*a;
}
}
Now, setting a to 10 will make b() return 100. It also means you cannot assign value to b(), but if you always want its value to be a*a this is probably also what you expect anyway.
I also suggest that you keep a private and add accessor methods for it, but that's a different story altogether.
(*) Assuming a single thread and/or proper coordination in case of multiple threads.
Note that int b = a * a; simply does a calculation and stores the result. Java does not remember where the result came from. If a changes, you will need to manually update b to propagate that change.
These are primitives not references. Changing one does not affect the other.
Not sure what are you trying to do.
Once that second line
int b = a* a
is processed by the jvm, it will not be remembered by the jvm. Only value of b will remain in memory.
Related
If I have a class like such:
public class First {
int x = 1;
}
and a second class:
class Main {
public static void main(string args[]) {
First someObject = new First();
someObject.x = 2;
}
}
is only someObject.x equal to 2 or would any object of class First being created afterwards be initialized with it's x attribute being equal to 2. If not, how would one change the default value of x for any object being made of class First?
First of all, you need to read about what "pass by reference" really means. (For example, here.) Passing semantics refer to what happens to arguments in a procedure/method/subroutine/function call. In your example, there is no "passing" going on at all when you are assigning to the x field.
So your
In Java are object attributes passed by reference to other classes
is a meaningless and/or irrelevant question. (But the plain answer is that Java does not support "pass by reference". Period.)
As for what I think you are trying to ask, lets start with some facts:
The Field class declares x as an instance field.
Each instance of First has its own "copy" of the x field.
The x field is part of one and only one instance. It is not shared with any other First instance.
This is irrespective of the declared type of x ... modulo that a field whose declared type is a reference type will contain a reference to an object rather than the object itself. (But int is not a reference type.)
The new First() expression creates a new instance of the First class that is distinct from all other (past, present or future) instances of First and returns its reference.
So, in this code:
First f1 = new First();
First f2 = new First();
f1.x = 2;
System.out.println(f2.x); // prints 1.
We have two instances of First that f1 and f2 refer to (point at) distinct First instances. If you change the x field of one instance does not change the x field of the other intance. They are different fields.
However, if you had declared x as static in First, then x is no longer a distinct field for each First instance. It is now a shared by all instances of First.
As an addendum, how would one change the default value of x in the First class such that any new instance made afterwards would have a difference value of x to start?
Firstly int x = 1; in First is not defining a "default" value in the sense that Java uses that term. It is actually an initialization. (A default value is what you see if you DON'T have an initialization.)
If you wanted to implement application specific default value that is common to all instances of First and that can be changed retrospectively, you need to implement it in Java code. Maybe something like this:
public class First {
static int defaultX = 1;
private int x;
private boolean xSet = false;
public int getX() {
return xSet ? x : defaultX;
}
public void setX(int x) {
this.x = x;
this.xSet = true;
}
}
Note that in order to implement the defaulting behavior we want, we have to hide the x field (make it private) and implement the desired behavior in the getter and setter methods.
These two methods calculate the derivative of a monom, but I dont understand what is the difference between them, do they do the same thing? why does one have a return and the other one makes changes to the calling object?
Which one is better?
In general, how should I return objects?
public Monom Der()
{
double a = this.get_coef() * this.get_pow();
int b = this.get_pow() - 1;
return new Monom(a, b);
}
public void Der()
{
this.set_coefficient(this._power * this._coefficient);
this.set_power(this._power - 1);
}
This one
public Monom Der() {
double a = this.get_coef() * this.get_pow();
int b = this.get_pow() - 1;
return new Monom(a, b);
}
does not change the state of the instance, it is useful when you want to have immutable objects. It can be used to work with both states the initial state and the state after process
Monom initialMonom = new Monom(2, 2);
Monom theNewMonom = initialMonom.Der();
// do something with both initialMonom and theNewMonom
This one
public void Der() {
this.set_coefficient(this._power * this._coefficient);
this.set_power(this._power - 1);
}
changes the state of the current instance, so the instance is NOT immutable. It can be useful when the instance needs to be reused
Monom initialMonom = new Monom(2, 2);
// do something with initial monom
initialMonom.Der(); // mutate the initial monom
// do something with the new state
You can Google a bit for the details. It's quite many things at the beginning here.
Differences: One is returned an Object Monom, one is "void"
Why: It depends on your business or the purpose of the codes that you would like to build. Returned Object is used by the next step or just show data. "void" means you don't want to get any data but to do some actions in that method
Which is better: It's hard to say. As the previous explanation, it should depend on your need
How should you return: refer this: https://docs.oracle.com/javase/tutorial/java/javaOO/returnvalue.html
Keep going to search more/practice more. Then it's easier.
Hope this help.
The first method creates a new object which will contain the result of the operations, but do not affect the current object, the second one directly changes the object you're using.
While you say that both methods do the same, this it not neccessarily true, since your first method caluclates a result and returns it, your second method calculates the result, but assigns it to a state in the current object.
Lets consider the following class:
public class Dinner {
private Meal meal;
public Dinner(Meal meal) {
this.meal = meal;
}
public Meal getMeal(Meal meal) {
return meal;
}
public setMeal(Meal meal) {
this.meal = meal;
}
}
Here, setMeal modified the internal state of the object, but it has no return value. On the other hand, getMeal return the current state of the object, but does not modify it.
Think about what exactly you need in your use case: If you want to modify internal data of an object, then go with the second way. If you want to return for example, the result of a calculation or internal state, give something back to the caller, so he can operate with it.
In the end, this are just some ideas, implementing a particular problem always comes with a lot of different possibilities so there is no perfect answer to this question.
I have a class that generates hash code based only on limited amount of properties. One of the requirements for hashCode uniqueness is that one of the properties must be exactly the same object instance. See this sample code:
class A {
private B b;
public A(B p) {
b = p;
}
public int hashCode() {
???
}
}
Now the only cases where the hashCode will be equal is when a1.b == a2.b. The problem is that I don't know how to add object instance ID to hashCode. Using B.hashCode would fail - the fact that two object's hashCodes are equal doesn't mean the object are the same instance.
Edit: I really have problems explaining this problem. I'll try some more:
My A class has a property B b. When generating hashCode of A, two A should have same hashCode, if their b property is the same object instance. Along with this, two A's with different instances in b should have different hashCode. This should work regardless off how B.hashCode is generated.
Hash codes aren't actually required to be unique. It's useful for them to be as close to unique as possible, but it's unlikely that someone will compare an A object's hash to a B object's hash, and if they do, it's not a huge loss. That said, to reduce collisions between A and B hashes, you could XOR b's hash code with some fixed int:
public int hashCode() {
return b.hashCode() ^ 260299079;
}
If your concern is that you want A instances with equal but distinct b members to hash differently, rather than making sure A and B instances hash differently, you can use System.identityHashCode:
public int hashCode() {
return System.identityHashCode(b) ^ 260299079;
}
This isn't actually guaranteed to produce different values for different B objects, but it's very likely to.
Would that suffice?
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((b == null) ? 0 : b.hashCode());
return result;
}
The second solution is coming.
Use a combination of the runtime class and your b property.
public int hashCode() {
return getClass().hashCode() ^ b.hashCode();
}
http://www.javapractices.com/topic/TopicAction.do?Id=29
Above is the article which i am looking at. Immutable objects greatly simplify your program, since they:
allow hashCode to use lazy initialization, and to cache its return value
Can anyone explain me what the author is trying to say on the above
line.
Is my class immutable if its marked final and its instance variable
still not final and vice-versa my instance variables being final and class being normal.
As explained by others, because the state of the object won't change the hashcode can be calculated only once.
The easy solution is to precalculate it in the constructor and place the result in a final variable (which guarantees thread safety).
If you want to have a lazy calculation (hashcode only calculated if needed) it is a little more tricky if you want to keep the thread safety characteristics of your immutable objects.
The simplest way is to declare a private volatile int hash; and run the calculation if it is 0. You will get laziness except for objects whose hashcode really is 0 (1 in 4 billion if your hash method is well distributed).
Alternatively you could couple it with a volatile boolean but need to be careful about the order in which you update the two variables.
Finally for extra performance, you can use the methodology used by the String class which uses an extra local variable for the calculation, allowing to get rid of the volatile keyword while guaranteeing correctness. This last method is error prone if you don't fully understand why it is done the way it is done...
If your object is immutable it can't change it's state and therefore it's hashcode can't change. That allows you to calculate the value once you need it and to cache the value since it will always stay the same. It's in fact a very bad idea to implement your own hasCode function based on mutable state since e.g. HashMap assumes that the hash can't change and it will break if it does change.
The benefit of lazy initialization is that hashcode calculation is delayed until it is required. Many object don't need it at all so you save some calculations. Especially expensive hash calculations like on long Strings benefit from that.
class FinalObject {
private final int a, b;
public FinalObject(int value1, int value2) {
a = value1;
b = value2;
}
// not calculated at the beginning - lazy once required
private int hashCode;
#Override
public int hashCode() {
int h = hashCode; // read
if (h == 0) {
h = a + b; // calculation
hashCode = h; // write
}
return h; // return local variable instead of second read
}
}
Edit: as pointed out by #assylias, using unsynchronized / non volatile code is only guaranteed to work if there is only 1 read of hashCode because every consecutive read of that field could return 0 even though the first read could already see a different value. Above version fixes the problem.
Edit2: replaced with more obvious version, slightly less code but roughly equivalent in bytecode
public int hashCode() {
int h = hashCode; // only read
return h != 0 ? h : (hashCode = a + b);
// ^- just a (racy) write to hashCode, no read
}
What that line means is, since the object is immutable, then the hashCode has to only be computed once. Further, it doesn't have to be computed when the object is constructed - it only has to be computed when the function is first called. If the object's hashCode is never used then it is never computed. So the hashCode function can look something like this:
#Override public int hashCode(){
synchronized (this) {
if (!this.computedHashCode) {
this.hashCode = expensiveComputation();
this.computedHashCode = true;
}
}
return this.hashCode;
}
And to add to other answers.
Immutable object cannot be changed. The final keyword works for basic data types such as int. But for custom objects it doesn't mean that - it has to be done internally in your implementation:
The following code would result in a compilation error, because you are trying to change a final reference/pointer to an object.
final MyClass m = new MyClass();
m = new MyClass();
However this code would work.
final MyClass m = new MyClass();
m.changeX();
This question already has an answer here:
What are the differences pre condition ,post condition and invariant in computer terminology [closed]
(1 answer)
Closed 9 years ago.
For example I have the following code:
public class Calc(){
final int PI = 3.14; //is this an invariant?
private int calc(int a, int b){
return a + b;
//would the parameters be pre-conditions and the return value be a post-condition?
}
}
I am just confused on what exactly these terms mean? The code above is what I think it is, however can anyone point me into the right direction with my theory?
Your code is in a contract with other bits and pieces of code. The pre-condition is essentially what must be met initially in order for your code to guarantee that it will do what it is supposed to do.
For example, a binary search would have the pre-condition that the thing you are searching through must be sorted.
On the other hand, the post-condition is what the code guarantees if the pre-condition is satisfied. For example, in the situation of the binary search, we are guaranteed to find the location of what we were searching for, or return -1 in the case where we don't find anything.
The pre-condition is almost like another thing on top of your parameters. They don't usually affect code directly, but it's useful when other people are using your code, so they use it correctly.
A invariant is a combined precondition and postcondition. It has to be valid before and after a call to a method. A precondition has to be fullfilled before a method can be run and a postcondition afterwards.
Java has no mechanisms for the condition checking built in but, here's a little example.
public class Calc {
private int value = 0;
private boolean isValid() {
return value >= 0;
}
// this method has the validity as invariant. It's true before and after a successful call.
public void add(int val) {
// precondition
if(!isValid()) {
throw new IllegalStateException();
}
// actual "logic"
value += val;
// postcondition
if(!isValid()) {
throw new IllegalStateException();
}
}
}
As you can see the conditions can be violated. In this case you (normally) use exceptions in Java.
private int calc(int a, int b){
return a + b;
//would the parameters be pre-conditions and the return value be a post-condition?
}
Is a function that takes two int and returns an int, which is the summation of a and b.
You would normally call the calc function in main as
public static void main(String[] args)
{
int a = 3, b = 4;
int sum = calc(a, b);
}
when you do that, a copy of a and b is passed to calc but the original values of a and b are not affected by the calc function as parameters are passed by value in Java.
A precondition is something that has to be true about the parameters that a function takes. So it isn't enough to say what the variables are, but you need to say something about their nature. For example, a and b must be integers. A post condition states what must be true after the function completes. In your example, it would be the fact that your function must produce the sum of a and b. The precondition and post condition can actually result in two methods, especially in a language like Java. What if you had a precondition that stated simply "The two parameters must be numerical". Then you would have to account for not only integers, but floating points.
Hope that helps.
Just a word of warning, casting a floating-point number (3.14) to an int is going to leave you with trouble. You might want to cast it to a float:
final float PI = 3.14f;
final means that the variable can no longer be changed.
a and b are just parameters that you pass into calc(). Before, they can be called whatever you want them to be, but inside calc() you can refer to them as a and b.
So you can have this:
int foo = 5;
int bar = 7;
int sum = calc(foo, bar); //12