Why doesn't Java have initializer lists like in C++? - java

In C++, you can use an initializer list to initialize the class's fields before the constructor begins running. For example:
Foo::Foo(string s, double d, int n) : name(s), weight(d), age(n) {
// Empty; already handled!
}
I am curious why Java does not have a similar feature. According to Core Java: Volume 1:
C++ uses this special syntax to call field constructors. In Java, there is no need for it because objects have no subobjects, only pointers to other objects.
Here are my questions:
What do they mean by "because objects have no subobjects?" I don't understand what a subobject is (I tried looking it up); do they mean an instantiation of a subclass which extends a superclass?
As for why Java does not have initializer lists like C++, I would assume that the reason is because all fields are already initialized by default in Java and also because Java uses the super keyword to call the super(or base in C++ lingo)-class constructor. Is this correct?

In C++, initializer lists are necessary because of a few language features that are either not present in Java or work differently in Java:
const: In C++, you can define a fields that are marked const that cannot be assigned to and must be initialized in the initializer list. Java does have final fields, but you can assign to final fields in the body of a constructor. In C++, assigning to a const field in the constructor is illegal.
References: In C++, references (as opposed to pointers) must be initialized to bind to some object. It is illegal to create a reference without an initializer. In C++, the way that you specify this is with the initializer list, since if you were to refer to the reference in the body of the constructor without first initializing it you would be using an uninitialized reference. In Java, object references behave like C++ pointers and can be assigned to after created. They just default to null otherwise.
Direct subobjects. In C++, an object can contain object directly as fields, whereas in Java objects can only hold references to those objects. That is, in C++, if you declare an object that has a string as a member, the storage space for that string is built directly into the space for the object itself, while in Java you just get space for a reference to some other String object stored elsewhere. Consequently, C++ needs to provide a way for you to give those subobjects initial values, since otherwise they'd just stay uninitialized. By default it uses the default constructor for those types, but if you want to use a different constructor or no default constructor is available the initializer list gives you a way to bypass this. In Java, you don't need to worry about this because the references will default to null, and you can then assign them to refer to the objects you actually want them to refer to. If you want to use a non-default constructor, then you don't need any special syntax for it; just set the reference to a new object initialized via the appropriate constructor.
In the few cases where Java might want initializer lists (for example, to call superclass constructors or give default values to its fields), this is handled through two other language features: the super keyword to invoke superclass constructors, and the fact that Java objects can give their fields default values at the point at which they're declared. Since C++ has multiple inheritance, just having a single super keyword wouldn't unambiguously refer to a single base class, and prior to C++11 C++ didn't support default initializers in a class and had to rely on initializer lists.

C++
There is a difference between
ClassType t(initialization arguments);
and
ClassType * pt;
The latter doesn't need to be initialized (set to NULL). The former does. Think of it as an integer. You can't have an int without a value, BUT you can have an int pointer without a value.
So when you have:
class ClassType
{
OtherClass value;
OtherClass * reference;
};
Then the declaration:
ClassType object;
automatically creates an instance of OtherClass in value. Therefore, if OtherClass has initialization, it must be done in the ClassType constructor. However, reference is just a pointer (address in memory) and can remain uninitialized. If you want an instance of OtherClass you must use
object.reference = new OtherClass(initialization arguments);
Java
There is only
class ClassType
{
OtherClass reference;
}
This is equivalent to a pointer in C++. In this case when you do:
ClassType object = new ClassType();
You don't automatically create an instance of OtherClass. Therefore, you don't have to initialize anything in the constructor unless you want to. When you want an object of OtherClass you can use
object.reference = new OtherClass();

Because Java does not need them to allow initialization of fields whose type has no zero-value.
In C++
class C {
D d;
}
without a member initializer for d, D::D() will be called which makes it impossible to initialize the field if there is no zero-type for D. This can happen when D::D() is explicitly declared private.
In Java, there is a known zero-value for all reference types, null, so a field can always be initialized.
Java also does a bunch of work to make sure* that all final fields are initialized before first use and before the constructor ends, so while Java has a requirement like C++'s const field initialization requirement, it just overloads this.fieldName = <expression> in the constructor body to mean field initialization.
: modulo exceptions thrown in the ctor, overridden method calls from the base class, etc.

Related

Not understanding how my variables are initialized

so I think I'm missing something. I am aware that
If no constructor is supplied java makes one for you.
If there's a constructor defined, default constructor by java is not used.
Constructor is used to initialize variables
Here's some simple code:
class a {
int f; // a variable with no value
int c; // a variable later initialized by the constructor
int b = 5; // this will be second question, a less important one
a(){
c = 1; // Constructor initiatives C, but not F
}
public static void main(String[] args){
a var = new a();
System.out.print(var.f); // Please see my comment below
}
}
Here's what I do not understand. Why is var.f printed? I did not initialize f in the constructor, however, there's no compile error and 0 value is initialed. I don't understand how '0' is initialized to 'f' despite me not having used it in constructor
Regarding b = 5, I understand what this code leads to, however, I do not think I understand what/who does the initialization here, is it new operator or something else? Thanks.
Edit: since the answers so far are not addressing my question
I am aware of the default values. I thought it was the default constructor that assigned them, is it not? If not, what assigns default values?
Java like most of programming languages has default values for uninitialized variables. Every numeric type of variable is initialized to 0-related value.
Boolean is false as default.
Strings and all of the objects have null as their default value.
Check docs for more info: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
int is a primitive data type. By definition, primitives cannot be null as they are not objects and will have a default value if not initialized. See here: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
If you want to be able to have a variable that is not initialized, you can use the object equivalent of an int java.lang.Integer
Instance variables that are declared but not initialised are given a default value.
References take a default value of null.
Primitives take a default value of zero
In regards to your query on your primitive int variable b, the new operator is not required, the new operator is used when instantiating a reference. When an instantiating a reference an object is created and memory is allocated on the JVM for that object.
Strings are a reference variable, but may be instantiated using the new keyword for example:
String example = new String("abc");
System.out.println(example); // prints abc.
Usually you would just write:
String example = "abc";
In the latter the literal is placed in to the 'string pool'...
You can read more about the string pool here: http://examples.javacodegeeks.com/core-java/lang/string/java-string-pool-example/
If no constructor is supplied java makes one for you.
Correct.
If there's a constructor defined, default constructor by java is not used.
It is not generated.
Constructor is used to initialize variables
Correct.
c = 1; // Constructor initiatives C, but not F
Untrue. Your code initializes c. The generated constructor initializes both.
I did not initialize f in the constructor
No, but Java did.
Java generates the following code for a constructor:
A super call.
Default initialization code for all variables declared without initializers. The default values are false, zero, or null as appropriate to the type.
Calls to all anonymous initializer blocks. (2) and (3) happen in textual order and can therefore be interleaved with each other.
Regarding b = 5, I understand what this code leads to, however, I do not think I understand what/who does the initialization here, is it new operator or something else?
See above.
I am aware of the default values. I thought it was the default constructor that assigned them, is it not?
No.
If not, what assigns default values?
The constructor. Any constructor.

Constructors does not have any return types but then how object is created?

According to the definitions of constructors they don't have any return types,but while creating object we often do A a = new A(); which is responsible for creating the object a.
A a=new A();
Can anyone help me understanding the issue,what is actually happening in the case of constructors while creation of Object.
Constructors don't have return types, correct. But the expression new A() does have a result: A reference to the newly-created object.
Here's what happens with new A():
An object is created
It's given the type A
The relevant A constructor is called with this referring to that new object
Once initialization is done, the expression completes
The result of the expression is the reference to the new object
This process is described in this tutorial on the Oracle Java site.
In many ways, it would be more accurate to call constructors initializers: The construction happens because of the new operator, not the constructor.
The fact that constructors don't actually do the construction is made particularly clear when an object is processed by multiple constructors, as is very common. Consider:
List<String> m = new LinkedList<String>();
One object is created (ignoring any fields the list may need to initialize), but five different constructors get called to initialize that one object, because LinkedList<E> subclasses java.util.AbstractSequentialList<E> which subclasses java.util.AbstractList<E> which subclasses java.util.AbstractCollection<E> which subclasses java.lang.Object, and each of those classes has to get its chance to initialize its part of the object that was created. So in order:
JVM creates the object
Object() is called to initialize Object stuff
AbstractCollection() is called to initialize its stuff
Then AbstractList()
Then AbstractSequentialList()
Then LinkedList()
And then finally the resulting (one) object's reference becomes the result of the new expression
One object, but five constructors required to initialize it. :-)
Constructors need not to return anything. They just constructs the current instance. That's all their job, part of object creation.
Creating objects:
A a = new A();
Declaration: The code set in bold are all variable declarations that associate a variable name with an object type.
Instantiation: The new keyword is a Java operator that creates the object.
Initialization: The new operator is followed by a call to a constructor, which initializes the new object.
Constructor declarations look like method declarations—except
that they use the name of the class and have no return type - from
the java constructor docs
To understand the constructor, it is similarly important to understand how it differs from a method.
Constructors have one purpose in life: to initialize the new object and it's fields. Nothing more. The new keyword handles the creation of memory space.
You shouldn't consider new A() to be a call to the constructor, because there are more things that happen, than just the constructor running. The major steps, when you run new A() are these.
A chunk of memory is set aside - just enough for storing an object of class A.
The constructor is run.
A reference to the chunk of memory that was set aside is returned.
So the constructor itself isn't actually returning anything - and it's an error to have return this; or anything similar inside the constructor.
Return statement inside a constructor doesn't logically makes sense because the purpose of the constructor is to perform initialization. The object has not been created yet, the actual construction of the object happens in JVM.

Constructors do not have return type in Java

IF constructors in Java does not return any value- they do not have any return type then when an object is created like
ClassOne objectOne=new ClassOne();
how a reference referring to the object of ClassOne is returned. IS it JVM which returns the reference.
Constructors do have a return type. The return type is implicitly the type of the class that declares the constructor.
Or you could say that constructors have an explicit return type and no name. Or, you could say that both the constructor name and the return type name are the same ... though that is not strictly correct. (If you are really perverse you can actually declare a regular method whose name is the same as the class name, with an explicit return type. But don't try this in any code that you want other people to read. They will throw stones at you ....)
Granted, the type is not explicitly declared. But it doesn't need to be. (And if it was declared, people would complain even more about Java verbosity.)
Similarly, a return statement in constructor cannot have an expression. That is because a constructor implicitly returns the reference to the object being constructed; i.e. this.
When we say constructors don't have a 'return type' it is to mean that the developer does not need to put an explicit/direct return type or even the key word void in front of the constructor name.
A constructor is to be used with the 'new' keyword since the purpose of the constructor is to initialize the members of a class and put the newly created/instantiated object to the allocated memory space by the 'new' keyword. Finally, the constructor is supposed to give back the memory address (location) to the left side. To explain this better consider the following example.
Circle c;
c = new Circle();
the left side Circle c creates a pointer (object name or ref type c) to hold the memory address of instances of type (from class) Circle. Only memory address of Circle classes or their sub classes if there is/are are allowed to be stored in c.
new keyword creates a memory location for the object to be created
Circle() constructor will create the object, place the object to the allocated memory and then assigns the memory address to the reference 'c'.
If constructors do not return a value this assignment statement would be meaningless. In this case our constructor returns a memory address of instance of Circle.
In summary, when we say a constructor does not return a value, it is to mean that the developer is not required to place a return type in front of the Constructor name as it is the case with other methods.
Hope this helps,
Thanks

How does the special variable "this" know exactly which Object to refer to in a program in JAVA? [duplicate]

This question already has answers here:
Using the keyword "this" in java [duplicate]
(12 answers)
Closed 9 years ago.
If the special variable this refers to an Object in a variable/method that is being used. How does it know exactly which object it must refer to out of various objects in a program?
The mechanism is almost disappointingly simple.
Each instance method actually takes one more argument than you declare for it, and that extra argument is assigned to this. Java syntax just thinly disguises this. When you write
list.get(0);
you have actually written
get(list, 0);
in a slightly modified way. The Java runtime resolves which get method to call by inspecting the type of that first argument and locating the appropriate get method in its class.
this points to the current object instance that it is used in.
If you define a class A with a method() that contains a this reference then you create two instances of the class
A a1 = new A();
A a2 = new A();
If you call a1.method() then this will refer to a1, if you call a2.method() then this will refer to a2
A a = new A();
a.doSomething(i) // is same as calling doSomething(a, i).
So, internally this refers to "a". The first argument to the function will be the object (there will only be one method that will be used by all objects). So, argument o will be the current object which has called this function.
From JAVA LANGUAGE SPECIFICATION
The keyword this may be used only in the body of an instance method,
instance initializer, or constructor, or in the initializer of an
instance variable of a class. If it appears anywhere else, a
compile-time error occurs.
When used as a primary expression, the keyword this denotes a value
that is a reference to the object for which the instance method was
invoked (§15.12), or to the object being constructed.
The type of this is the class C within which the keyword this occurs.
At run time, the class of the actual object referred to may be the
class C or any subclass of C.
The keyword this is also used in a special explicit constructor
invocation statement, which can appear at the beginning of a
constructor body (§8.8.7).
You can also refer to Oracle Tutorials
Within an instance method or a constructor, this is a reference to the current object — the object whose method or constructor is being called. You can refer to any member of the current object from within an instance method or a constructor by using this.
Oracle Java Tutorials
this is a very important keyword that can differentiate between parent and child class objects. this refers to the present context in which object has too be referred to..!!

Constructor is static or non static

As per standard book constructor is a special type of function which is used to initialize objects.As constructor is defined as a function and inside class function can have only two type either static or non static.My doubt is what constructor is ?
1.)As constructor is called without object so it must be static
Test test =new Test();//Test() is being called without object
so must be static
My doubt is if constructor is static method then how can we frequently used this inside
constructor
Test(){
System.out.println(this);
}
Does the output Test#12aw212 mean constructors are non-static?
Your second example hits the spot. this reference is available in the constructor, which means constructor is executed against some object - the one that is currently being created.
In principle when you create a new object (by using new operator), JVM will allocate some memory for it and then call a constructor on that newly created object. Also JVM makes sure that no other method is called before the constructor (that's what makes it special).
Actually, on machine level, constructor is a function with one special, implicit this parameter. This special parameter (passed by the runtime) makes the difference between object and static methods. In other words:
foo.bar(42);
is translated to:
bar(foo, 42);
where first parameter is named this. On the other hand static methods are called as-is:
Foo.bar(42);
translates to:
bar(42);
Foo here is just a namespace existing barely in the source code.
Constructors are non-static. Every method first parameter is implicit this (except static) and constructor is one of that.
Constructors are NOT static functions. When you do Test test =new Test(); a new Test object is created and then the constructor is called on that object (I mean this points to the newly created object).
The new keyword here is the trick. You're correct in noting that in general, if you're calling it without an object, a method is static. However in this special case (i.e., preceded by the new keyword) the compiler knows to call the constructor.
The new operator returns a reference to the object it created.
new Test(); // creates an instance.
The System.out.println(this); is called after the new operator has instantiated the object
Not static. Read about constructors http://www.javaworld.com/jw-10-2000/jw-1013-constructors.html.
Neither.
Methods can be divided into 2 types: static/non-static methods, aka class/instance methods.
But constructors are not methods.
When we talk about static class then it comes to our mind that methods are called with class name,But in case of constructor ,Constructor is initialized when object is created So this proves to be non-static.
Constructors are neither static (as called using class name) or non-static as executed while creating an object.
Static:
Temp t= new Temp();
The new operator creates memory in the heap area and passes it to the constructor as Temp(this) implicitly. It then initializes a non-static instance variable defined in a class called this to the local parameter variable this.
Below example is just for understanding the concept, if someone tries to compile it, it will give the compile-time error.
class Temp{
int a;
Temp this; //inserted by compiler.
Temp(Temp this){ //passed by compiler
this.this=this; // initialise this instance variable here.
this.a=10;//when we write only a=10; and all the non-static member access by this implicitly.
return this; // so that we can't return any value from constructor.
}
}
Constructor is static because:
It is helping to create object.
It is called without object.
Constructor is used to initialize the object and has the behavior of non-static methods,as non-static methods belong to objects so as constructor also and its invoked by the JVM to initialize the objects with the reference of object,created by new operator

Categories