What are java object fields initialized with? - java

Is it null for Object type?
class C {
int i;
String s;
public C() {}
}
Will s be always null?
What about simple types as int? What will that be? Zero or an arbitrary value?
What about local variables in methods?
public void meth() {
int i;
}
What is the unitialized value of i?
Relying on such default values, however, is generally considered bad
programming style.
Ok, what do you suggest we do?
class A {
String s = "";
int i = 0;
}
OR:
class A {
String s;
int i;
public A() {
// default constructor
s = "";
i = 0;
}
}
Which is better and why?

From suns java tutorial
It's not always necessary to assign a
value when a field is declared. Fields
that are declared but not initialized
will be set to a reasonable default by
the compiler. Generally speaking, this
default will be zero or null,
depending on the data type. Relying on
such default values, however, is
generally considered bad programming
style.
The following chart summarizes the
default values for the above data
types.
Data Type Default Value (for fields)
byte 0
short 0
int 0
long 0L
float 0.0f
double 0.0d
char '\u0000'
boolean false
String (or any object) null
Local variables are slightly
different; the compiler never assigns
a default value to an uninitialized
local variable. If you cannot
initialize your local variable where
it is declared, make sure to assign it
a value before you attempt to use it.
Accessing an uninitialized local
variable will result in a compile-time
error.

For member variables:
The default value for String is null. The default value for primitives is 0 (or 0.0 for floating point values).
For local variables:
You must explicitly initialise a local variable before using it.
As to the second part of your question:
You can always say String s = ""; in the member variable definition, or s = ""; in the constructor. Then you know it will have a non-null value. (Also, in your setter you'd need to ensure that someone doesn't try and set it back to null.)

Fields: Objects default to null; ints, longs and shorts to 0; Strings to null; booleans to false. It's all here.
The compiler will force you to initialise variables declared in methods, local variables, yourself.

Primitive fields are initialized to 0 / false. Objects are initialized to null . But frankly, you could have tried that one..

As for the setter-method question: The whole point of setters is that they can check if the object passed conforms to the requirements of the class. e.g.
public void setS(String s) {
if (s == null)
throw new IllegalArgumentException("S must not be null");
this.s = s;
}
Or, with Google Collections/Google Guava:
public void setS(String s) {
this.s = Preconditions.checkNotNull(s, "S must not be null");
}
Of course, you can define arbitrary constraints, e.g.:
/**
* Sets the foo. Legal foo strings must have a length of exactly 3 characters.
*/
public void setFoo(String foo) {
if (foo == null)
throw new IllegalArgumentException("Foo must not be null");
if (foo.length() != 3)
throw new IllegalArgumentException("Foo must have exactly 3 characters");
...
Of course in such a case you should always state the correct range of values for your properties in the JavaDoc of the setter and/or of the class.

JLS 4.12.5. Initial Values of Variables
Each class variable, instance variable, or array component is
initialized with a default value when it is created (§15.9, §15.10.2):
For type byte, the default value is zero, that is, the value of
(byte)0.
For type short, the default value is zero, that is, the value of
(short)0.
For type int, the default value is zero, that is, 0.
For type long, the default value is zero, that is, 0L.
For type float, the default value is positive zero, that is, 0.0f.
For type double, the default value is positive zero, that is, 0.0d.
For type char, the default value is the null character, that is,
'\u0000'.
For type boolean, the default value is false.
For all reference types (§4.3), the default value is null.

Related

Delete value for previously assigned int field [duplicate]

Can an int be null in Java?
For example:
int data = check(Node root);
if ( data == null ) {
// do something
} else {
// do something
}
My goal is to write a function which returns an int. Said int is stored in the height of a node, and if the node is not present, it will be null, and I'll need to check that.
I am doing this for homework but this specific part is not part of the homework, it just helps me get through what I am doing.
Thanks for the comments, but it seems very few people have actually read what's under the code, I was asking how else I can accomplish this goal; it was easy to figure out that it doesn't work.
int can't be null, but Integer can. You need to be careful when unboxing null Integers since this can cause a lot of confusion and head scratching!
e.g. this:
int a = object.getA(); // getA returns a null Integer
will give you a NullPointerException, despite object not being null!
To follow up on your question, if you want to indicate the absence of a value, I would investigate java.util.Optional<Integer>
No. Only object references can be null, not primitives.
A great way to find out:
public static void main(String args[]) {
int i = null;
}
Try to compile.
In Java, int is a primitive type and it is not considered an object. Only objects can have a null value. So the answer to your question is no, it can't be null. But it's not that simple, because there are objects that represent most primitive types.
The class Integer represents an int value, but it can hold a null value. Depending on your check method, you could be returning an int or an Integer.
This behavior is different from some more purely object oriented languages like Ruby, where even "primitive" things like ints are considered objects.
Along with all above answer i would like to add this point too.
For primitive types,we have fixed memory size i.e for int we have 4 bytes and char we have 2 bytes. And null is used only for objects because there memory size is not fixed.
So by default we have,
int a=0;
and not
int a=null;
Same with other primitive types and hence null is only used for objects and not for primitive types.
The code won't even compile. Only an fullworthy Object can be null, like Integer. Here's a basic example to show when you can test for null:
Integer data = check(Node root);
if ( data == null ) {
// do something
} else {
// do something
}
On the other hand, if check() is declared to return int, it can never be null and the whole if-else block is then superfluous.
int data = check(Node root);
// do something
Autoboxing problems doesn't apply here as well when check() is declared to return int. If it had returned Integer, then you may risk NullPointerException when assigning it to an int instead of Integer. Assigning it as an Integer and using the if-else block would then indeed have been mandatory.
To learn more about autoboxing, check this Sun guide.
instead of declaring as int i declare it as Integer i then we can do i=null;
Integer i;
i=null;
Integer object would be best. If you must use primitives you can use a value that does not exist in your use case. Negative height does not exist for people, so
public int getHeight(String name){
if(map.containsKey(name)){
return map.get(name);
}else{
return -1;
}
}
No, but int[] can be.
int[] hayhay = null; //: allowed (int[] is reference type)
int hayno = null; //: error (int is primitive type)
//: Message: incompatible types:
//: <null> cannot be converted to int
As #Glen mentioned in a comment, you basically have two ways around this:
use an "out of bound" value. For instance, if "data" can never be negative in normal use, return a negative value to indicate it's invalid.
Use an Integer. Just make sure the "check" method returns an Integer, and you assign it to an Integer not an int. Because if an "int" gets involved along the way, the automatic boxing and unboxing can cause problems.
Check for null in your check() method and return an invalid value such as -1 or zero if null. Then the check would be for that value rather than passing the null along. This would be a normal thing to do in old time 'C'.
Any Primitive data type like int,boolean, or float etc can't store the null(lateral),since java has provided Wrapper class for storing the same like int to Integer,boolean to Boolean.
Eg: Integer i=null;
An int is not null, it may be 0 if not initialized. If you want an integer to be able to be null, you need to use Integer instead of int . primitives don't have null value. default have for an int is 0.
Data Type / Default Value (for fields)
int ------------------ 0
long ---------------- 0L
float ---------------- 0.0f
double ------------- 0.0d
char --------------- '\u0000'
String --------------- null
boolean ------------ false
Since you ask for another way to accomplish your goal, I suggest you use a wrapper class:
new Integer(null);
I'm no expert, but I do believe that the null equivalent for an int is 0.
For example, if you make an int[], each slot contains 0 as opposed to null, unless you set it to something else.
In some situations, this may be of use.

I did not initialize a variable yet I still receive an output

Here is my code:
class Xyz{
public static void main(String args[])
{
first fobj = new first(10);
for(int i=0;i<5;i++){
fobj.add();
System.out.printf("%s",fobj);
}
}
}
class first{
public int sum=0;
public final int num;
first(int x){
num=x;
}
public void add(){
sum+=num;
}
public String toString()
{
return String.format("sum = %d" ,sum);
}
}
output:
sum=10
sum=20
sum=30
sum=40
sum=50
In the class first I didn't initialize a variable named "sum" but I still get output. Can someone explain that to me?
asgfafgalsdfkjsaflkasflaskfalskfajlskfaskfaslkjflaskfaslkflasjkf.
Instance members are automatically initialized to default values, JLS-4.12.5 Initial Values of Variables
Each class variable, instance variable, or array component is initialized with a default value when it is created (§15.9, §15.10):
...
For type `int`, the default value is zero, that is, 0.
In Java, all the member variables are automatically initialized to their default values at the time of object creation even if you don't do it yourself. Default value of int is 0.
Class and instance data members are automatically defaulted to the all-bits-off value for their type (0 in the case of int), even if you don't do it explicitly. Since sum is an instance data member, it's implicitly defaulted to 0.
This is covered by §4.12.5 of the Java Language Specification:
Each class variable, instance variable, or array component is initialized with a default value when it is created (§15.9, §15.10.2):
For type byte, the default value is zero, that is, the value of (byte)0.
For type short, the default value is zero, that is, the value of (short)0.
For type int, the default value is zero, that is, 0.
For type long, the default value is zero, that is, 0L.
For type float, the default value is positive zero, that is, 0.0f.
For type double, the default value is positive zero, that is, 0.0d.
For type char, the default value is the null character, that is, '\u0000'.
For type boolean, the default value is false.
For all reference types (§4.3), the default value is null.

Initialising instance variables as null, "" or 0

When initialising variables with default values:
What is the difference between:
private static String thing = null;
and
private static String thing = "";
I'm not understanding which is better and why nor what is the best way to deal with other data types.
private static int number = 0;
private static double number = 0;
private static char thing = 0;
Sorry I struggle learning new languages.
Except for initializing String to an empty string
private static String thing = "";
the other assignments are unnecessary: Java will set all member variables of primitive types to their default values, and all reference types (including java.String) to null.
The decision to initialize a String to a null or to an empty string is up to you: there is a difference between "nothing" and "empty string" *, so you have to decide which one you want.
* The differences between "nothing" and "empty string" stem from the observation that no operations are possible on a null string - for example, its length is undefined, and you cannot iterate over its characters. In contrast, the length of an empty string is well-defined (zero), and you can iterate over its characters (it's an empty iteration).
When you make:
private static String ptNo = "";
you are creating a variable ptNo and making it to refer an object String "".
When you make:
private static String ptNo = null;
you are creating a variable, but it doesn't refer to anything.
null is the reserved constant used in Java to represent a void reference i.e a pointer to nothing.
In Java null and an empty are not the same thing.
From suns java tutorial
It's not always necessary to assign a value when a field is declared. Fields that are declared but not initialized will be set to a reasonable default by the compiler. Generally speaking, this default will be zero or null, depending on the data type. Relying on such default values, however, is generally considered bad programming style.
The following chart summarizes the default values for the above data types.
Data Type Default Value (for fields)
byte 0
short 0
int 0
long 0L
float 0.0f
double 0.0d
char '\u0000'
String (or any object) null
boolean false
Local variables are slightly different; the compiler never assigns a default value to an uninitialized local variable. If you cannot initialize your local variable where it
is declared, make sure to assign it a value before you attempt to use it. Accessing an uninitialized local variable will result in a compile-time error.
"" is an actual string with empty value.
null means that the String variable points to nothing.
As an example,
String a="";
String b=null;
a.equals(b) returns false because "" and null do not occupy the same space in memory.

Comparison of two null objects from two different types

public void m1(Integer f) {
...
}
public void m1(Float f) {
...
}
public void main() {
m1(null); // error: the method m1(Integer) is ambiguous for the type Main
m1((Integer) null); // success
}
Given the above example, we can admit in some ways that null is typed. So why do the following lines print true? Sure o1 and o2 both have no value (i.e. null), but they aren't from the same type (Integer vs Float). I firstly thought false would have been printed.
Integer i = null;
Object o1 = (Object) i;
Float f = null;
Object o2 = (Object) f;
System.out.println(o1 == o2); // prints true
// in short:
System.out.println(((Object) ((Integer) null)) == ((Object) ((Float) null))); // prints true
All null values are untyped and are equal. You can pass it to different reference types but it makes no difference for comparison purposes.
It is not the null value which is typed but the reference to the null which can be typed.
A common question is what happens here
class A {
public static void hello() { System.out.println("Hello World"); }
public static void main(String... args) {
A a = null;
a.hello();
System.out.println("a is an A is " + (a instanceof A)); // prints false.
}
}
The compiler sees the type of a as an A so the static method is called. But the value referenced is null and untyped.
The only operations you can perform with null without causing a NullPointerException is to assign or pass it without examining it or comparing it with another reference.
BTW
In short: The compiler will select a method based on the type of the reference, at runtime the execution is based on the class of the object referenced. At runtime null is treated as any type or no type or you get a NullPointerException if you try to dereference it.
"==" in Java checks to see if it is the same instance rather than simply "are they equal?". There is no concept of multiple instances of null in Java. If you compare null to null, you will always receive true regardless of type.
The reason why you cannot then pass null as an argument to a method with the same name as another with different parameter types is because either method could be a candidate to be called without further type context. Rather than guess which one that might be, it correctly indicates an error.
see http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.1
null belongs to the "null type". The "null type" has only one value - the null.
The null type is a subtype of every reference type. Therefore we can do
Integer i = null;
(Integer)null
In another word, null is a valid value in every reference type.
(Think of a type as a set of values; the types of a value is the sets it belongs to; "subtype" means "subset". )
Given the above example, we can admit that null is NOT typed: when you call m1(null), compiler cannot determine the type of the actual parameter and cannot decide which method to invoke. All nulls are equal and not typed, and so (null==null)==true.
Null does not have a type, but a reference (to null or anything else) has a type. We can declare two reference variables with different types, but the null they refer to is the same thing in both cases:
Integer a = null;
Double b = null;
In your example,
m1((Integer) null);
the compiler uses the type of the reference it is passed to work out which overloaded method to call, not the type of the null value itself.
In your example it proves that the compiler cannot identity the type (of null) and decide which method to call. So you have to explicity give the type. Also null == null will be always true; no matter whatever cast you do it doesnt change or give null a type.This post has a long description on null.

Type casting the `Object` type variables

I need to call a function with the following signature.
createColumn (N name, V value, Serializer<N> nameSerializer, Serializer<V> valueSerializer)
I want to pass variables of type Object which might have been assigned values of integer or string, I want the type casting to be performed automatically..according to the values that I assigned to Object type variables instead of explicit cast like this:-
Object object1= "MY_AGE";
// string value assigned to to object type variable
Object object2= 31; // integer value assigned to object type variable
createColumn ((String)object1, (int)object2, ....); // Since the datatype of object1 & object2 would not be same everytime while I am calling this function in a for loop, I want that it should automatically cast according to the value I assign to it.* So I am seeking something like this, if possible:-
createColumn (object1, object2, ....);
You can call the following since you don't want to check at compile time that the types match,
createColumn(object1, object2, (Serializer)serializer1, (Serializer)serializer2);
EDIT: This compiles for me (with an "Unchecked" warning)
interface Serializer<T> { }
public static <N,V> void createColumn (N name, V value, Serializer<N> nameSerializer, Serializer<V> valueSerializer) {
}
public static void main(String[] args) throws NoSuchFieldException {
Object object1 = "hi";
Object object2 = 31;
Serializer<String> serializer1 = null;
Serializer<Integer> serializer2 = null;
createColumn(object1, object2, (Serializer) serializer1, (Serializer) serializer2);
}
As I understand your question is not about casting (which deals with compile-time declared types), but conversion (which deals with runtime type of objects).
Consider using String.valueOf() method for your Object arguments. For both Integer and String it will produce their String representation.
I don't think it is possible, you have given the variable a type object and i'm not aware of any way to determine if it is really an int or string unless you use some ugly logic to see what characters the value consists of but that isn't going to be fool proof unless the value will always be either an integer or a string.
Do you need to pass integers or can everything just be passed as a string?

Categories