I noticed surprising behaviour.
I can write so:
Integer integer = 0;
integer++;
But I cannot write so:
getInteger()++;
Here's my getInteger() method:
public static Integer getInteger(){
return 0;
}
For me two snippets look the same.
But the second piece of code returns an error:
unexpected type
getInteger()++;
^
required: variable
found: value
Why is the second construction forbidden?
Often, I feel forced to write "ugly" code like this:
obj.set(obj.get()+1);
It looks redundant.
x++ is not the same as x + 1. It's short for x += 1, i.e. x = x + 1; increment, then assign. So getInteger()++ means getInteger() = getInteger() + 1, which makes no sense. You're adding one to a value, not incrementing a variable.
Apart from that, ++ works on int but not Integer, but even if you were returning an int you couldn't increment it with ++:
class Test {
static public void main() {
getint()++;
}
static int getint() {
int a = 0;
return a;
}
}
gives
Test.java:3: error: unexpected type
getint()++;
^
required: variable
found: value
(In C++ you could make this work with references, but Java doesn't have those.)
8++ will not make sense,while
int x=8;
x++;
do make sense
because x++, is working like x+=1, i.e x=x+1
and 8=8+1 is something not acceptable.
As it says, it requires a variable for ++ operator. ++ increments a value that is stored somewhere, so the incremented value is now stored in that location. your function just returns a value , which is not a variable.
It's as simple as Rahul mentioned in the comment.
//This works
x=5;
x++; //Now x=6 since x++ is equivalent to x=x+1;
//This doesn't work
5++; //this doesn't even make sense, trying to do 5=5+1??
//similarly, getNumber() is just a value that is returned, it is a value, not a variable
//So it is like the second case
//This doesn't work
getNumber()++; //Trying to do getNumber()=getNumber()+1; ??
Why second constructions is forbid?
Integer is immutable, so you couldn't change it anyway. int is mutable but since it only returns a copy on the value, this won't work either.
e.g.
public static Integer getInteger(){
return 0;
}
// what would this do
getInteger()++;
// now the method has been changed to
public static Integer getInteger(){
return 0+1;
}
// so now
System.out.println(getInteger()); // prints 1 ??
obj.set(obj.get()+1);
This breaks encapsulation as well. I would suggest a method like this
AtomicInteger i = new AtomicInteger(0);
i.incrementAndGet();
or you could have your own
i.incr();
You are not returning an int, you're returning an Integer object. The Integer class is immutable and has no ++ operator of its own.
Also, the ++ operator requires that its operand be an lvalue, i.e. an assignable variable as opposed to a value. The result of getInteger() is the latter.
In the case of your first test:
Integer integer = 0; integer++;
Java's autoboxing allows the use of the ++ operator, but only because Java automatically converts the Integer into an int and then back again, and because the variable integer is an lvalue. It's more or less equivalent to:
int tmp_int = integer.intValue();
int result = tmp_int++;
integer = Integer.getInteger(tmp_int);
(void)result;
result - the effective "value" of the expression isn't integer because you've used the "post increment" version of ++, so the result is the value that integer had before it was incremented.
Related
Is this code safe in Java?
public class HelloWorld {
public static void main (String args[]) {
HelloWorld h = new HelloWorld();
int y = h.getNumber(5);
int z = h.getNumber (6);
if (y == 10)
System.out.println("true");
}
public int getNumber(int x) {
int number = 5;
number = number + x;
return number;
}
}
My co-worker says that int number will be placed on the stack and when getNumber returns it will be popped off and could potentially be overwritten.
Is the same code potentially unsafe in C?
The HelloWorld class has no fields, and is therefore immutable. You can call your getNumber(x) function as many times as you'd like, from any thread, using the same object, and it will always give the same result for the same argument.
Maybe your co-worker is recalling horror stories in C where you can have something like static int number, which "belongs" to the method and which would get overwritten. Or maybe she's thinking about "return by reference"; even if it were, you'd be referencing a brand-new object every time because number is newly instantiated for every method call.
Your coworker is correct, sort of, but they apparently misunderstand what is going on.
public int getNumber(int x) {
int number = 5;
number = number + x;
return number;
}
Yes the value of 5 + 5 or 5 + 6 will be placed on the stack, but there is no danger of them being overwritten, they will properly be placed into y or z.
I suspect the confusion is from C (this type code works fine in C as well), but for pointers instead of primitives. Returning a result of malloc from a function in C can be "challenging" if you don't do it right.
I am a little bit confused about the following piece of code:
public class Test{
int x = giveH();
int h = 29;
public int giveH(){
return h;
}
public static void main(String args[])
{
Test t = new Test();
System.out.print(t.x + " ");
System.out.print(t.h);
}
}
The output here is 0 29, but I thought that this has to be a compiler error, because the variable h should have not been initialized when it comes to the method giveH(). So, does the compilation go through the lines from top to bottom? Why is this working? Why is the value of x 0 and not 29?
The default value of int is 0 (see here). Because you initialize x before h, giveH will return the default value for a int (eg 0).
If you switch the order like this
int h = 29;
int x = giveH();
the output will be
29 29
Compilation in Java doesn't need the method to be declared before it is used. The Java tutorial goes into a bit more detail on initialization.
Here's a way to think about it: the compiler will make a note to look for a method called giveH somewhere in scope, and it will only error if it leaves the scope and doesn't find it. Once it gets to the giveH declaration then the note is resolved and everyone is happy.
Also, the variable initialization for instance variables in Java is moved to the beginning of the constructor. You can think of the lines above being split into two parts, with the declaration for x and h above, and the assignment inside the constructor.
The order of declaration does matter in this case. When the variable x is initialized, h has the default value of 0, so giveH() will return that default value. After that, the variable h is given the value 29.
You can also look at the Java Language Specification sections on Field Initialization and Forward References During Field Initialization.
#Maloubobola has provided the correct answer, but since you don't seem to fully understand yet, let me try to elaborate.
When Test is created, it runs the variable initialization (x = giveH(), h= 29) once. Your misunderstanding may be that variable x is always determined by giveH(), whereas it only determines it's value when x is initialized.
That's why the order of the statements is crucial here; x is initialized before h, and therefore h is 0 when giveH() is called at x's initialization.
It's bad practice to use a method in the field initializer. You can fix this by making h final. Then it will be initialized when the class is loaded.
import java.util.ArrayList;
public class Test {
int x = giveH();
final int h=29;
final public int giveH(){
return h;
}
public static void main(String args[]) {
Test t = new Test();
System.out.print(t.x + " ");
System.out.print(t.h);
}
}
If we do not initialize the value for non static variables like x in this program JVM will provide default value zero for class level non static variables.
Once declared, all the array elements store their default values.
Elements in an array that store objects default to null.
Elements of an array that store primitive data types store:
0 for integer types (byte, short, int,long);
0.0 for decimal types (float and double);
false for boolean;
\u0000 for char data.
Actauls values will come only when we give initialize them
I am following the U of Helsinki's Java course and I have difficulty on example 75.1.
link
The problem is that my method doesn't affect the object's value. For example, the exercise requires an output of
value: 10
value: 9
value 8
However, I receive:
value: 10
9
value: 10
9
value: 10.
The code I use is:
public void decrease() {
System.out.println(this.value - 1);
Additionally, I cannot use a return statement as the method must be void.
Right. Generally speaking, "print x - 1" does not change the value of x. So, we must change this.value. We do so through assignment:
public void decrease() {
this.value = this.value - 1; // decrease the value
System.out.println(this.value); // print the new value
}
We can actually do this with a single line with the unary -- operator:
public void decrease() {
System.out.println(--this.value); // Decrease this.value first,
// then print the new value
}
Notice the placement of --. If we write --this.value, we decrease and then print. If we write this.value--, we print then decrease.
You can print then decrement the value:
System.out.println(this.value--);
Just decrement the value. The caller seems to take care of printing (by calling printValue)
public void decrease() {
this.value--;
}
Merely invoking this.value - 1 does not change the value of value. If you want to actually change the value, you have two choices:
Use a decrement statement (value--), or
Reassign the variable (which is long-hand for the decrement).
value = value - 1
Never mind, I've got it.
code needed to be:
this.value = this.value - 1;
System.out.println(this.value - 1);
Will only print the value -1 there is no assignment.
You need something like
System.out.println(this.value = this.value -1);
or
System.out.println(this.value -= 1);
I have a string that I would like to convert into an integer before storing it as a property of an object. Although I can use regular if statements, I wanted to use a ternary operation to build my understanding of it. Here is the code I've tried
field_num = (((boolean bool_is_int = is_integer(string)) == true) ? (Integer int = Integer.parseInt(string)) : null);
What I'm trying to do (very basically) is set "field_num" (which is of type int) to the value of "string" if it is equal to an integer (by first converting it). is_integer is a function I have to check if a string is equal to an integer. It returns a boolean value.
Thanks for any help.
I would do something like this:
Integer theint = is_integer(thestr) ? Integer.parseInt(thstr) : null;
You cannot assign NULL to an intrinsic int but you can to an Integer object. Typically, of course, you'd simply rely on the parseInt() call throwing an exception rather than explicitly testing for integerness of the string beforehand.
field_num = is_integer(string) ? Integer.parseInt(string): -1;
In plain english this says if 'string' is an integer then parse string for the int and set it to field_num otherwise, set it to -1. -1 is arbitrary. you should instead use a number that is invalid for field_num.
You do not need is_integer(string) == true because that evaluates to the same thing as is_integer(string). You also don't need to set the boolean bool_is_int because unless you actually want that value later in the program.
You should just use an if/else statement. The Ternary operator is useful when you you want to set a variable to one of two values based on a condition. In your example, you don't want to set the value if the string is not an integer so ternary doesn't fit the situation well.
Keep it simple :)
int field_num = isInt(string) ? Integer.parseInt(string) : Integer.MAX_VALUE;
if (field_num == Integer.MAX_VALUE) {
// error; string is not a valid representation of int
}
To determine Whether a String represents an int value :
public static boolean isInt(String s) {
try {
Integer.parseInt(s);
} catch(NumberFormatException e) {
return false;
}
return true;
}
[Corrected]
Learn one thing at a time.
First, the ?: operator (more often referred to as the conditional operator, or the if/else operator; "ternary" just means it takes three arguments, and it's the only C operator that does so, hence the confusion)...
field_num = is_integer(string) ? Integer.parseInt(string) : null;
Ahhh. So field_num is an Integer. Would have help if you'd said that.
Second: Assignment-in-passing. If you don't know that you need to do this, and you can't make it perfectly obvious what you're doing and why, DON'T. It's hard to read, and it's rarely appropriate.
Also, "int" is not a legal variable name.
But if you insist:
Integer myint;
boolean bool_is_int;
field_num = (bool_is_int = is_integer(string)) ? (myint = Integer.parseInt(string)) : null;
What's myint's value in the false/else case? It's left as whatever it had been set to previously. This might be what you intended, but it's very hard for someone reading your code to understand.
In most cases, unless the ?: is a very simple one that can be read at a glance -- (foo!=null) ? foo.doSomething() : defaultValue -- you're better off using a real if/then/else statement. It's likely to be just as efficient after the compiler and JIT are done with it, and it'll be a lot easier to maintain.
Here is a java line of code that i have failed to understand.
String line = "Some data";//I understand this line
int size;//I understand this line too
size = Integer.valueOf(line,16).intValue();//Don't understand this one
What i know is Integer.ValueOf(line) is the same as Integer.parseInt(line) , is not so? Correct me if i am wrong; Thanks.
Integer.ValueOf(line,16) converts string value line into an Integer object. In this case radix is 16.
intValue() gets the int value from the Integer object created above.
Furthermore, above two steps are equivalent to Integer.parseInt(line,16).
In order to get more INFO please refer Java API Documentation of Integer class.
Yes, this is equivalent to:
size = Integer.parseInt(line, 16);
Indeed, looking at the implementation, the existing code is actually implemented as effectively:
size = Integer.valueOf(Integer.parseInt(line, 16)).intValue();
which is clearly pointless.
The assignment to -1 in the previous line is pointless, by the way. It would only be relevant if you could still read the value if an exception were thrown by Integer.parseInt, but as the scope of size is the same block as the call to Integer.valueof, it won't be in scope after an exception anyway.
Please look at the data type of the variables on the left hand side.
public class Test {
public static void main(String[] args) {
String s = "CAFE";
Integer m = Integer.valueOf(s, 16);
int n = m.intValue();
System.out.println(n);
}
}
Integer is a reference type that wraps int, which is a primitive type.
" = Integer.valueOf().intValue()"
and Example:
String myNumber = "54";
int c = Integer.valueOf(myNumber).intValue(); // convert strings to numbers
result:
54 // like int (and before was a String)