Java heap and stack missunderstood - java

I have read my question one more time and I think the example was not good enought to show where was my confusion. So I will show a different example.
public class Main {
public static void main(String args[]) {
Foo foo = new Foo();
foo.deleteOtherFoo();
}
}
public class Foo {
private OtherFoo otherFoo;
public Foo() {
otherFoo = new OtherFoo();
}
public void deleteOtherFoo() {
this.otherFoo = null;
}
}
public class OtherFoo {
public OtherFoo() {}
}
If I follow what I know about stack and heap, I can say:
my draw
in the frame deleteOtherFoo what do I have as parameters? because I know I can only have primitive type or reference type value. In that case I have a reference type Foo.otherFoo ? a value that contain a pointer of a pointer ?
Because when I put this.otherFoo = null, I remove the ref of otherFoo from the object foo.

code lives in an entirely different place. Code is effectively unchanging, save some crazy 'reload this class from disk again please' shenanigans (which the JVM does support but that's an entirely different can of worms).
So where does 'the method' live? Well, nowhere. The CODE of the method lives in what used to be called permgen. It's definitely not the stack, never gets garbage collected, and no matter how many Foo objects you make, the code is located in memory only once.
And that's that.. until you call the method.
When you call the method, if it's non-static, it needs 'an instance'. This is, as far as the JVM is concerned, pretty much 100% the same as a parameter: If you call foo.doThingie(a);, then both foo and a are parameters to the doThingie method. These are put on the stack, and then doThingie is executed. Once doThingie finishes execution, the stack is reset to the point before doThingie was invoked, so, 'foo' and 'a' are now gone.
In java, all non-primitives are 'references' which is just javaspeak for 'pointers'. So when I say 'foo and a are on the stack', what I really mean is 'a pointer, into the heap, pointing at the data (i.e., the fields) that represent an instance of Foo, is on the stack'.

Related

How is a child object constructed in Java?

In java, how is a child object constructed?
I just started inheritance and these few points are not very clear to me:
Does the child object depend only on the child class' constructor, or does it also depend on the parent's constructor? I need some details about that point.
Also, is super() always called by default in a child constructor?
Any other information regarding this topic is appreciated.
I don't think "A child object" is a good way to think about this.
You're making an object. Like all objects, it is an instance of some specific class, (After all, new SomeInterface() does not compile) and like (almost) all objects, it is made because some code someplace (doesn't have to be your code, of course) ran the java expression new SomeSpecificClass(args); somewhere.
We could say it is a 'child object' because SomeSpecificClass is a child class of some other class.
But that's rather useless. That means the only way to ever make a new 'non-child' object would be to write new Object(); - after all, all classes except java.lang.Object are a child class: If you write public class Foo {}, java will interpret that exactly the same as if you had written public class Foo extends java.lang.Object {}, after all.
So, barring useless* irrelevancies, all objects are child objects, and therefore as a term, 'child object', I'd not use that.
That also means that ALL object creation goes through this 'okay and in what order and how do the constructors work' song and dance routine.
How it works is probably most easily explained by desugaring it all. Javac (the compiler) injects things if you choose to omit them, because a lot of things that feel optional (such as a constructor, a super call, or an extend clause), at the class file / JVM level, aren't**.
Sugar #1 - extends clause
Already covered: if you have no extends clause on your class def, javac injects extends java.lang.Object for you.
Sugar #2 - no super call in constructor
A constructor must either call some specific super constructor on its very first line, or, it it must call some other constructor from the same class on its very first line (this(arg1, arg2);). If you don't, java will inject it for you:
public MyClass(String arg) { this.arg = arg; }
// is treated as:
public MyClass(String arg) {
super();
this.arg = arg;
}
Notably including a compiler error if your parent class has no zero-arg constructor available.
Sugar #3: No constructor
If you write a class that has no constructor, then java makes one for you:
public YourClass() {}
It will be public, it will have no args, and it will have no code on it. However, as per sugar #2 rule, this then gets expanded even further, to:
public YourClass() {super();}
Field inits and code blocks get rewritten to a single block.
The constructor isn't the only thing that runs when you make new objects. Imagine this code:
public class Example {
private final long now = System.currentTimeMillis();
}
This code works; you can compile it. You can make new instances of Example, and the now field will hold the time as it was when you invoked new Example(). So how does that work? That feels a lot like constructor code, no?
Well, this is how it works: Go through the source file top to bottom and find every non-static initializing code you can find:
public class Example {
int x = foo(); // all non-constant initial values count
{
x = 10;
// this bizarre constructor is legal java, and also
// counts as an initializer.
}
}
and then move all that over to the one and only initializer that classes get, in the order you saw them.
Ordering
So, via sugar rules we have reduced ALL classes to adhere to the following rules:
ALL classes have a parent class.
ALL classes have at least 1 constructor.
ALL constructors invoke either another constructor or a constructor from parent.
There is one 'initializer' code block.
Now the only question is, in what order are things executed?
The answer is crazy. Hold on to your hats.
This is the order:
First, set all fields to 0/false/null of the entire 'construct' (the construct involves every field from Child all the way down to Object, of course).
Start with the actual constructor invoked on Child. Run it directly, which means, start with the first line, which neccessarily is either a this() or a super() invocation.
Evaluate the entire line, notably, evaluate all expressions passed as arguments. Even if those are themselves invocations of other methods. But, javac will do some minor effort to try to prevent you from accessing your fields (because those are all uninitialized! I haven't mentioned initializers yet!!).
Yeah, really. This means this:
public class Example {
private final long x = System.currentTimeMillis();
public Example() {
super(x); // x will be .... 0
// how's that for 'final'?
}
}
This will either end up invoking the first line of some other constructor of yours (which is itself also either a this() or a super() call). Either we never get out of this forest and a stack overflow error aborts our attempt to create this object (because we have a loop of constructors that endlessly invoke each other), or, at some point, we run into a super() call, which means we now go to our parent class and repeat this entire song and dance routine once more.
We keep going, all the way to java.lang.Object, which by way of hardcoding, has no this() or super() call at all and is the only one that does.
Then, we stop first. Now the job is to run the rest of the code in the constructor of j.l.Object, but first, we run Object's initializer.
Then, object's constructor runs all the rest of the code in it.
Then, Parent's initializer is run. And then the rest of the parent constructor that was used. and if parent has been shifting sideways (this() invokes in its constructors), those are all run in reverse order as normal in method invocations.
We finally end up at Child; its initializer runs, then the constructor(s) run in order, and finally we're done.
Show me!
class Parent {
/* some utility methods so we can run this stuff */
static int print(String in) {
System.out.println("#" + in);
return 0;
// we use this to observe the flow.
// as this is a static method it has no bearing on constructor calls.
}
public static void main(String[] args) {
new Child(1, 2);
}
/* actual relevant code follows */
Parent(int arg) {
print("Parent-ctr");
print("the result of getNow: " + getNow());
}
int y = print("Parent-init");
long getNow() { return 10; }
}
class Child extends Parent {
Child(int a, int b) {
this(print("Child-ctr1-firstline"));
print("Child-ctr1-secondline");
}
int x = print("Child-init");
Child(int a) {
super(print("Child-ctr2-firstline"));
print("Child-ctr2-secondline");
}
final long now = System.currentTimeMillis();
#Override long getNow() { return now; }
}
and now for the great puzzler. Apply the above rules and try to figure out what this will print.
#Child-ctr1-firstline
#Child-ctr2-firstline
#Parent-init
#Parent-ctr
#the result of getNow: 0
#Child-init
#Child-ctr2-secondline
#Child-ctr1-secondline
Constructor execution ordering is effectively: the first line goes first, and the rest goes last.
a final field was 0, even though it seems like it should never be 0.
You always end up running your parent's constructor.
--
*) You can use them for locks or sentinel pointer values. Let's say 'mostly useless'.
**) You can hack a class file so that it describes a class without a parent class (not even j.l.Object); that's how java.lang.Object's class file works. But you can't make javac make this, you'd have to hack it together, and such a thing would be quite crazy and has no real useful purpose.
In inheritance, the construction of a child object depends on at least one parent constructor.
Calling the super () method is not mandatory. By default, Java will call the parent constructor without argument except if you precise a custom constructor.
Here an example
Mother
public class Mother {
int a;
public Mother() {
System.out.println("Mother without argument");
a = 1;
}
public Mother(int a) {
System.out.println("Mother with argument");
this.a = a;
}
}
child
public class Child extends Mother {
public Child() {
System.out.println("Child without argument");
}
public Child(int a) {
super(a);
System.out.println("Child with argument");
}
}
If you do this :
Child c1 = new Child();
you will get :
Mother without argument
Child without argument
If you do this :
Child c1 = new Child(a);
You will get :
Mother with argument
Child with argument
But if you change the second child constructor to and remove the super(arg) the parent constructor without argument will be called :
public Child(int a) {
// super(a);
System.out.println("Child with argument");
}
You will get :
Mother without argument
Child with argument
May be this course for beginners can help you Coursera java inheritance

Strugling with the keyword this in Java

I've read a lot of explanations for the use of keyword 'this' in java but still don't completely understand it. Do i use it in this example:
private void login_BActionPerformed(java.awt.event.ActionEvent evt) {
if(user_TF.getText().equals("admin")&& pass_PF.getText().equals("admin")){
this.B.setVisible(true);
}else{
JOptionPane.showMessageDialog(null, "Warning!", "InfoBox: "+"Warning", JOptionPane.INFORMATION_MESSAGE);
}
this.user_TF.setText("");
this.pass_PF.setText("");
}
It's supposed to open a new window if a user and pass match. Do i use 'this' keyword anywhere here?
I think there are two main usages you should know:
If you have a class variable with name N, and a method variable with name N, then to distinguish them, use this.N for class variable and N for method variable. Screenshot displaying possible usage
Imagine you have 2 constructors. One takes String name, another takes name + age. Instead of duplicating code, just use this() to call another constructor. Another screenshot displaying the usage
In your case, I don't see any LOCAL (method) variables of name 'B', so I guess you can do without it.
Any non static method of the class needs an object of that class to be invoked. Class has the blueprint of the state and behavior to modify and read the state. Object is the realization of this blueprint. Once object is created , it has those states and methods.
Suppose you have below code.
public class A{
int property;
public void foo(){
bar();
}
public void bar(){
property = 40;
}
}
public class B{
public static void main(String[] args){
A obj = new A();
obj.foo();
}
}
Lets try to answer few questions.
Q1. Inside the mwthod foo we invoke bar , we have not used any explicit object to invoke it (with . dot operator), upon which object is the method bar invoked.
Q2. Method bar tries to access and modify the variable named property. Which object does this state called property belong to ?
Answers
A1. Object referred by A.this (it is same as this) . It is the object which has invoked foo method which is implicitly made available insode the called method. The object upon which execution of the method takes places can be accessed by this.
A2. same as answer to Q1.
The object at anytime can be accessed by Classname.this inside the non static methods or blocks of the class.

Java casting understanding

public class Maryland extends State { Maryland() { /* null constructor */ }
public void printMe() { System.out.println("Read it."); }
public static void main(String[] args) {
Region mid = new State();
State md = new Maryland();
Object obj = new Place();
Place usa = new Region();
md.printMe();
mid.printMe();
((Place) obj).printMe();
obj = md;
((Maryland) obj).printMe();
obj = usa;
((Place) obj).printMe();
usa = md;
((Place) usa).printMe();
}
}
class State extends Region {
State() { /* null constructor */ }
public void printMe() { System.out.println("Ship it."); }
}
class Region extends Place {
Region() { /* null constructor */ }
public void printMe() { System.out.println("Box it."); }
}
class Place extends Object {
Place() { /* null constructor */ }
public void printMe() { System.out.println("Buy it."); }
}
Hi There.
I'm trying to understand the behaviour of the above main method which prints the following output when run.
Read it.
Ship it.
Buy it.
Read it.
Box it.
Read it.
I'm particularly struggling to understand the output of the last two printMe methods in the main function.
My understanding is that the first two print me operations will use there super classes printMe method as the objects have not been explicitly downcast to the sub class and thus are considered to be State and Region objects respectively by the Java compiler.
I also believe I understand the next two outputs in which the classes are downcast and thus the subclass printMe functions will override the superclass functions.
However I am struggling to understand what is occurring in the last two printMe methods. I can see that the variable obj is initially declared as an Object and then downcast as a Place is assigned a reference to the usa object(of type Place). So why is the output then of type region in this instance? I feel I am missing fundamental here in my understanding.
In Java, instance method calls follow inheritance. No matter what the reference type is, it will call the method of the type of the actual object.
The type of the reference only determine which methods the compiler knows you can call. e.g.
String hi = "Hello";
Object A = hi;
String hiToString = A.toString(); // calls String.toString();
int l = A.length(); // won't compile even though the String in A has a length() method.
Note: for static methods, the instance is ignored and it is the compile time type which determines which method is called.
In Java, non-static methods are called with late-binding, which means we cannot make sure which function it will call until run-time.
My understanding is that the first two print me operations will use there super classes printMe method as the objects have not been explicitly downcast to the sub class and thus are considered to be State and Region objects respectively by the Java compiler.
Explicitly downcast does nothing in this code. Downcast is actually performed.
Object md is still a reference to State and Object mid is a reference of Region. Compiler will never know which printMe() will be called. It only checks that State and Region classes have the function printMe() or not.
At run-time, when the md.printMe() is called, JVM will check the Runtime type information (RTTI) of md, and know it is a Object of State class. Therefore, the printMe() function in the State class is called, no matter what md is declared. (Of course, you need to override the printMe() in the State class. If you don't, State class will inherit the printMe() function from its superclass Place, and the printMe() function in Place class will be called. You can check this by removing the printMe() function in your State class.)
According to these rules, the output is reasonable.
The type cast in ((Place) obj).printMe() is needed just because in Object class, there's no printMe() function in it. Still, the compiler can't make sure which function ((Place) obj).printMe() will called, it is decided at run-time. For example, if you change your ((Maryland) obj).printMe(); to ((Place) obj).printMe();, the output is still the same.
For static methods, these rules will not fit. You can read more information about them with the keywords "Overloading, Overriding and Hiding". These terminologies will help you to understand the inheritance system in Java.

Java: initialization sequence of object

There is a code which is given as a task for a junior Java developers. I use Java during five years and this piece of code completely confusing me:
public class Main {
String variable;
public static void main(String[] args) {
System.out.println("Hello World!");
B b = new B();
}
public Main(){
printVariable();
}
protected void printVariable(){
variable = "variable is initialized in Main Class";
}
}
public class B extends Main {
String variable = null;
public B(){
System.out.println("variable value = " + variable);
}
protected void printVariable(){
variable = "variable is initialized in B Class";
}
}
The output will be:
Hello World!
variable value = null
But if we change String variable = null; to String variable; we will have:
Hello World!
variable value = variable is initialized in B Class
The second output is more clear for me.
So, as far as I know the sequence of inizialisation in Java like this:
We go to the root of the class hierarchy (for Java it is always Object class), when we come to this root parent class:
All static data fields are initialized;
All static field initializers and static initialization blocks are executed;
All non-static data fields are initialized;
All non-static field initializers and non-static initialization blocks are executed;
The default constructor is executed;
Then we repeat the procedure for the underlying child class.
Also there is post which describes the behavior of the this keyword in context of a superclass - Calling base class overridden function from base class method
Based on the rules given above, I assume to have sequence like this:
We are going to create a new instance of class B;
We go to the part class Main;
Initialize main.variable with null;
Then we move to the default constructor of class Main;
Constructor calls method b.printVariable() in class Main; (Why doesn't it call main.printvariable? We don't have this key word here.)
The field b.variable "variable is initialized in B Class"
Now we come back to the class B;
We should initialize field b.variable with null value, am I right?;
The default constructor of class B executed
Please, can someone give a complete and full explanation of how this inheritance inizialisation sequence works. And why changing String variable = null; to String variable; leads to another output.
The sequence is:
Main -> "Hello"
Main -> new B()
B() -> Main() -> b.printVariable() -> sets the variable
Back to initialising B, so variable=null occurs.
So basically, the super object Main() is constructed before any intialisation events of class B. Which means variable=null occurs later. This makes sense as otherwise B could break the initialisation of Main.
Joshua Bloch covers a lot of good ground in his effective java book about how dangerous inheritance is to get right, I would recommend it.
First, you need to understand, what happens when you write variable = null;. When is that code executed. This basically determines the output.
Before I begin, I should also mention that when you create an object of class B, the printVariable() function of the main class is not called. Instead, always the printVariable() of B will be called.
Keeping this in mind, when you have variable = null, the execution for B's constructor will begin. First Main() will be called, which will call the printVariable() method. At last, variable=null, will be called overwriting the variable variable.
In the other case, where you do not initialize variable=null, the variable set by the printVariable() function will not be overwritten, hence you get what you were expecting.
In summary, this is the order of execution of statements, when you do new B():
Main() //super constructor
B#printVariable()
initializtion of variables in B's constructor (if any) [i.e. variable=null, if present]
This is a nice exercise! But it's not a fair question to ask junior developers. This one is for seniors. But to make this text useful during the technical interview, I'd modified it by adding an argument to the Main's constructor:
public Main(String something){
printVariable();
}
If the person will answer what will happen, then remove the argument and ask the original questions. If the person won't answer - there is no need to continue - s/he is junior.
You can also remove the protected qualifier in class B and ask what will happen if you have a goal not to hire this person :)

C++'s out parameter object creation and JNA

Disclaimer: I ignore pretty much everything about C++, so I hope I'm not saying stupid things here, if I am, please feel free to correct me.
As a Java developer, when I want to create a new object, I use a constructor method that will allocate this object in memory and return a handle on it for me, and I will store this handle in a variable, I do it like this.
Foo o = new Foo();
But in C++, I've been given to understand, that despite the fact it is possible to do so
Foo createFoo(){
Foo f;
f.doSomething();
return f;
}
// ...
Foo f = createFoo();
I can also define a handle by myself, and then call a initializer on it that will allocate memory and bind the handle on it, like this:
void initializeFoo(Foo **f){
f.doSomething();
return;
}
// ...
Foo f;
initializeFoo(&f);
So my question is, what happens when we want to use those C++ methods in Java, with JNA?
Let's suppose I have the following C++ header:
typedef struct Foo f;
Foo createFoo();
void initializeFoo(Foo **f);
As I don't have any idea on what a Foo is, or what the Foo structure contains, I'm just going to create a JNA PointerType to declare my structure:
public class Foo extends PointerType{
public Foo(Pointer address) {
super(address);
}
public Foo() {
super();
}
}
Using the createFoo method should be pretty easy as well:
public class TestFoo{
static{
System.loadLibrary("foolib");
}
public static void main(String[] args){
FooLib lib = (FooLib)Native.loadLibrary("foolib", FooLib.class);
Foo f = lib.createFoo();
}
Right?
But my question is, how can I use the initializeFoo function??? I suppose I would have to create a Pointer and give it to the function, but how do I create a non NULL pointer in JNA? I tried the following code, but it results in an EXCEPTION_ACCESS_VIOLATION.
public class TestFoo{
static{
System.loadLibrary("foolib");
}
public static void main(String[] args){
FooLib lib = (FooLib)Native.loadLibrary("foolib", FooLib.class);
Foo f = new Foo();
lib.initializeFoo(f); // EXCEPTION_ACCESS_VIOLATION
lib.initializeFoo(f.getPointer()); // EXCEPTION_ACCESS_VIOLATION
}
Any idea?
Thanks!
Foo f;
initializeFoo(&f);
initializeFoo() does not "allocate memory and bind the handle" for f, as you say. Foo f; creates f and allocates it in memory. initializeFoo() could do something like assign values to f's member properties, and the like, as well as create another Foo object and assign it to f, but it does not do what you say.
On the other hand,
Foo *f;
f = new Foo();
declares a Foo pointer. new allocates memory and creates a Foo object, and assigns the memory location to f (you can think of a pointer as a integer containing an address).
I think you want to learn more about C++ and pointers before you go any further.
As I don't have any idea on what a Foo is, or what the Foo structure contains, I'm just going to create a JNA PointerType to declare my structure
This makes it impossible to allocate memory for Foo, as you have to know how much memory you need to allocate. For c structures jna needs a java class mirroring the structure or if you at least know its size you can try to use the Memory class which has a ctor taking a size argument.
For c++ structures and classes using c++ features like inheritance this fails since the required memory and layout depends on the compiler and enabled optimisations.

Categories