This question already has answers here:
How does auto boxing/unboxing work in Java?
(4 answers)
Closed 2 years ago.
So I came across a bug caused by following example:
I have static method
private static Foo findFoo(int id) {
//we use id here not important
}
Then I used it inside another method like
private static updateFoo(final Integer id, final String newData) {
final Foo existingData = findFoo(id);
// use existing data and update or make new
}
The problem is when updateFoo is called with null in id argument, the intValue() is implicitly called (I think) when calling findFoo(id) and causes NPE.
I thought Java enforces strong typing that prevents cases where Objects are passed to arguments when primitives are expected. Is there a general rule here when implitic calls are made? And could this be picked up by compiler/IDE and possibly enforce or warn?
This always happens if you use a wrapper class as its primitive counter-part. int cannot be null, so you must call intValue() onto the wrapper class.
You can either do a null check before calling findFoo() or just use the primitive int for updateFoo() or the wrapper class in findFoo().
I thought Java enforces strong typing that prevents cases where Objects are passed to arguments when primitives are expected.
The type of Integer fits, so its type is covered. It is just an implicite casting (unboxing) in this case which is totally fine.
Related
This question already has answers here:
What is the difference between an int and an Integer in Java and C#?
(26 answers)
Closed 2 years ago.
I have seen many times in code that people use int or Integer to declare variable in beans. I know int is datatype and Integer is wrapper class.
My question is, in which condition int or Integer should be used and is there any advantage of either of them over another?
My question is, in which condition int or Integer should be used and is there any advantage of either of them over another?
Well, you should use the reference type Integer whenever you have to. Integer is nothing more than a boxed int. An Object with a single field containing the specified int value.
Consider this example
public class Ex {
int field1;
Integer field2;
public Ex(){}
}
In this case field1 will be initialized with the value 0 while field2 will be initialized with null. Depending on what the fields represent, both approaches might be advantageous. If field1 represents some kind of UUID, would you want it to be initialized with a zero value?
I wouldn't worry too much about the performance implications of Autoboxing. You can still optimize after you get your code running.
For more information take a look at the documentation
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Integer.html
You always use int, pretty much.
Integer should rarely be used; it is an intermediate type that the compiler takes care of for you. The one place where Integer is likely to appear is in generics, as int is simply not legal there. Here is an example:
List<Integer> indices = new ArrayList<Integer>();
int v = 10;
indices.add(v);
The above works: It compiles with no errors and does what you think it would (it adds '10' to a list of integer values).
Note that v is of type int, not Integer. That's the correct usage; you could write Integer here and the code works as well, but it wouldn't be particularly idiomatic java. Integer has no advantages over int, only disadvantages; the only time you'd use it, is if int is straight up illegal. Which is why I wrote List<Integer> and not List<int> as the latter is not legal java code (yet - give it a few versions and it may well be legal then, see Project Valhalla).
Note also that the compiler is silently converting your v here; if you look at the compiled code it is as if javac compiled indices.add(Integer.valueOf(v)) here. But that's fine, let the compiler do its thing. As a rule what the compiler emits and what hotspot optimizes are aligned; trust that what javac emits will be relatively efficient given the situation.
int is a primitive type, a value type for number literals.
it is used whenever and wherever you just want to do some basic arithmetical operation;
it is a value type, so it's stored in the Stack area of the memory, hence operations on it are much faster;
whenever it's needed, compiler implicitly and automatically casts back and forth (a.k.a Boxing and Unboxing) from int to Integer and vice versa;
Integer is a Class, which is a reference type and you instantiate an Object of that type.
you create an object of that class, which means, that you also have some methods and operations on that object;
any time you do some arithmetic operation on the instance of Integer, under the hood, it's still implemented by int primitives, and it's just wrapped into box/container;
it is a reference type / object, which is very important, as you can Serialize or Deserialize it;
it also has some very useful utility factory methods, like Integer.valueOf(..) for example, to parse the String as an integer;
it can be well used into declarations of the generic types and it, as a class, supports the hierarchy as well. For instance, it extends Number, and you can make use of this;
it is stored in the Heap area of the memory.
int is a primitive and Integer is an object .
From an memory footprint point of view , primitive consume less memory than object and also primitives are immutable (since they use pass by value ) .
Here is a good article on when to use what :
https://www.baeldung.com/java-primitives-vs-objects
This question already has answers here:
What does this block of code do?
(6 answers)
Closed 8 years ago.
When I do this:
baseApp = (MyApp)this.getContext();
What am I actually doing?
as opposed to doing:
baseApp = myApp.doSomething();
I'm not concern with the methods but understanding the construction.
How are those 2 above different and why?
Whats the meaning of doing (MyApp)?
Whats the meaning of doing (MyApp)?
It is a reference type cast.
It checks that the reference produced by evaluating the RHS (i.e. this.getContext() ) is compatible with MyApp and then uses it that as the result of the expression (with that type). If the reference given by the RHS expression is not for a compatible type, a runtime exception will be thrown.
By contrast ...
baseApp = myApp.doSomething();
is just calling the doSomething() method and assigning it ... WITHOUT doing a typecast. If the doSomething() method does not deliver a value of the correct type, you will get a compilation error.
For the record, there is no "instantiation" going on here. Instantiation is done using the new operator1.
1 - ... or by calling specific reflective methods.
Firstly where are you calling this from? An Activity?
The first line is casting the current objects context to a MyApp object then assigning it to an object named baseApp. And I also assume baseApp is of type MyApp.
The second line is assigning the value returned from the method named doSomething() to baseApp
but more information is needed to compare further.
This question already has answers here:
Why cast null to Object?
(4 answers)
Closed 9 years ago.
Take a look at the following example:
class nul
{
public static void main (String[] args)
{
System.out.println (String.valueOf((Object)null));
System.out.println (String.valueOf(null));
}
}
The first println writes null but the second throws a NullPointerException.
Why is only the second line worth an exception? And what is the difference between the two nulls? Is there a real null and a fake null in Java?
The first invocation will call the String.valueOf(Object) method, as you have explicitly typecasted null to Object reference. Conversely, the second one will invoke the overloaded String.valueOf(char[]) method, as char[] is more specific than Object for a null argument.
There are other overloaded versions of this method that accept primitive parameters, but those are not a valid match for a null argument.
From JLS §15.12.2:
There may be more than one such method, in which case the most
specific one is chosen. The descriptor (signature plus return type) of
the most specific method is one used at run time to perform the method
dispatch.
A method is applicable if it is either applicable by subtyping
(§15.12.2.2), applicable by method invocation conversion (§15.12.2.3),
or it is an applicable variable arity method (§15.12.2.4).
[...]
If several applicable methods have been identified during one of the
three phases of applicability testing, then the most specific one is
chosen, as specified in section §15.12.2.5.
Now check the source code of both the methods:
// This won't throw NPE for `obj == null`
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
// This will throw `NPE` for `data == null`
public static String valueOf(char data[]) {
return new String(data);
}
There are lots of overloaded String.valueOf methods in Java. Further, in Java null has any and all types so that anything (that isn't a primitive) can be null.
So, when you call (String.valueOf((Object)null) you call the valueOf method that takes an Object as use explicitly cast null to Object.
In the second example you don't explicitly cast the null to any particular type so in fact you call the valueOf method with a char[] which throws an NPE.
From the JLS §15.12.2
The second step searches the type determined in the previous step for
member methods. This step uses the name of the method and the types of
the argument expressions to locate methods that are both accessible
and applicable, that is, declarations that can be correctly invoked on
the given arguments.
There may be more than one such method, in which case the most
specific one is chosen. The descriptor (signature plus return type) of
the most specific method is one used at run time to perform the method
dispatch.
In this case char[] is more specific than Object so it is called when no explicit cast of null is made.
Although I accepted already an answer I would like to add the exact answer to the question, because the two answers concentrate on explaining the trap I walked into.
The difference between (Object)null and null is that the type of the first is forced to Object but the type of the second is not, as one could think, forced to Object. Instead it could also be an array instead of an object.
So the conclusion is: pass (Object)null instead of null as an argument to a method to be sure to get exactly the method working on objects instead of any other method working on arrays.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Which constructor is chosen when passing null?
I recently came across this curiosity while coding a few days back and can't seem to figure out why the following happens:
Given the class below
public class RandomObject{
public RandomObject(Object o){
System.out.println(1);
}
public RandomObject(String[] s){
System.out.println(2);
}
}
When the call new RandomObject(null); is made the output is always 2 regardless of the order in which the constructors were created. Why does null refer to the string array rather than the object?
The key here is that Object is the super type of String[]
Java uses the most specific available method to resolve such cases. Null can be passed to both methods without compilation errors so Java has to find the most specific method here. The version with String[] is more specific - therefore it will be chosen for execution.
Someone else has had this question earlier, check this post
If there are two cases to choose from, the compiler will first try to pick the more specific case. In this case, String will be picked over Object.
In the other question it was String str instead of String[] s
Thus, since String[] is a more specific datatype than its super type Object, it is picked.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is Java “pass-by-reference”?
I found an unusual Java method today:
private void addShortenedName(ArrayList<String> voiceSetList, String vsName)
{
if (null == vsName)
vsName = "";
else
vsName = vsName.trim();
String shortenedVoiceSetName = vsName.substring(0, Math.min(8, vsName.length()));
//SCR10638 - Prevent export of empty rows.
if (shortenedVoiceSetName.length() > 0)
{
if (!voiceSetList.contains("#" + shortenedVoiceSetName))
voiceSetList.add("#" + shortenedVoiceSetName);
}
}
According to everything I've read about Java's behavior for passing variables, complex objects or not, this code should do exactly nothing. So um...am I missing something here? Is there some subtlety that was lost on me, or does this code belong on thedailywtf?
As Rytmis said, Java passes references by value. What this means is that you can legitimately call mutating methods on the parameters of a method, but you cannot reassign them and expect the value to propagate.
Example:
private void goodChangeDog(Dog dog) {
dog.setColor(Color.BLACK); // works as expected!
}
private void badChangeDog(Dog dog) {
dog = new StBernard(); // compiles, but has no effect outside the method
}
Edit: What this means in this case is that although voiceSetList might change as a result of this method (it could have a new element added to it), the changes to vsName will not be visible outside of the method. To prevent confusion, I often mark my method parameters final, which keeps them from being reassigned (accidentally or not) inside the method. This would keep the second example from compiling at all.
Java passes references by value, so you get a copy of the reference, but the referenced object is the same. Hence this method does modify the input list.
The references themselves are passed by value.
From Java How to Program, 4th Edition by Deitel & Deitel: (pg. 329)
Unlike other languages, Java does not allow the programmer to choose whether to pass
each argument by value or by reference. Primitive data type variables are always passed
by value. Objects are not passed to methods; rather, references to objects are passed to
methods. The references themselves are passed by value—a copy of a reference is passed
to a method. When a method receives a reference to an object, the method can manipulate
the object directly.
Used this book when learning Java in college. Brilliant reference.
Here's a good article explaining it.
http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html
Well, it can manipulate the ArrayList - which is an object... if you are passing an object reference around (even passed by value), changes to that object will be reflected to the caller. Is that the question?
I think you are confused because vsName is modified. But in this context, it is just a local variable, at the exact same level as shortenedVoiceSetName.
It's not clear to me what the exact question within the code is. Java is pass-by-value, but arrays are pass-by-reference as they pass no object but only pointers! Arrays consist of pointers, not real objects. This makes them very fast, but also makes them dangerous to handle. To solve this, you need to clone them to get a copy, and even then it will only clone the first dimension of the array.
For more details see my answer here: In Java, what is a shallow copy? (also see my other answers)
By the way, there are some advantages as arrays are only pointers: you can (ab)use them as synchronized objects!