class FDemo {
int x;
FDemo(int i) {
x = i;
}
protected void finalize() {
System.out.println("Finalizing " + x);
}
void generator(int i) {
FDemo o = new FDemo(i);
System.out.println("Creat obj No: " + x); // this line
}
}
class Finalize {
public static void main(String args[]) {
int count;
FDemo ob = new FDemo(0);
for(count=1; count < 100000; count++)
ob.generator(count);
}
}
}
In the line i have commented, the value of x always shows 0(value of x in object ob), why isnt showing the value of object o?? i know if i use o.x i ll be getting the value of x in object o. But still in this code why does it show the value of abject ob rather than object o??
If you want to reference the x in the FDemo you've just created, you should add a getX() function and call that instead of x, like David Wallace said. (I prefer using getters instead of .variable).
Add this to your class:
public int getX(){
return x;
}
And change your problematic line to this:
System.out.println("Creat obj No: " + o.getX());
That should fix it. As a side note, it's considered good practice to explicitly declare whether your variables and methods are private, public or protected.
Related
So this is basically my code
abstract class B
{
int x = 3;
B()
{
x+=2;
System.out.print("-x" + x + "\n"); // print -x5
x++; // 5 then 6
}
abstract int calculate();
abstract int calculate(int i);
}
class A extends B
{
int x = 2;
A()
{
System.out.print("-x" + calculate(2)+"\n");
}
#Override
int calculate()
{
return x;
}
#Override
int calculate(int i)
{
return(calculate()+i);
}
}
public class Test2 extends A
{
Test2()
{
x+=3;
}
#Override
int calculate()
{
return x + 6;
}
public static void main(String[] args) {
Test2 sub = new Test2();
System.out.print("-x" + sub.calculate()+"\n");
}
}
My problem here is after digging up about variable hiding I learned that if a instance variable is of the same name in both parent class and child class then the childclass hides the instance variable of the parent class. Also I have the prior knowledge that variables cannot be overridden when child class inherits parent class.
So now coming to the problem, in the code when A extends to B, why does the print statement inside constructor A() gives a value -x10? shouldn't it be -x8?? I dont understand how the variable is being changed here. I am new to java so any kind of knowledge will be greatly appreciated. :)
Ok so I have done some debugging and found that the calculate(void) method in class A returns 8. But how is that possible shouldn't it return 6? Please help!
The reason it prints -x10 is because A::calculate(2) calls the Test2::calculate(), which uses A::x to do the calculation.
The sequence of calls that happens is the following:
Test2() {
A()
B() {
B::x = 3
B::x += 2
System.out.print("-x" + x + "\n"); // print -x5
B::x++ // B::x is now 6
}
A::x = 2
System.out.print("-x" + calculate(2)+"\n")
A::calculate(2) {
return(calculate()+2);
Test2::calculate() {
return A::x + 6; // A::x is 2 here, so returns 8
}
} // returns calculate()+2, so returns 10
}
A::x += 3
}
I hope this is just code to test things out, because you should never allow this to happen in real code. You should never allow a method of a subclass to be called from the constructor of a base class, because the subclass is not initialised at that time. The Java compiler does its best to prevent that, but sometimes it does not detect it.
It is returning 8 because:
The line you called System.out.print("-x" + sub.calculate()+"\n"); in class A calls
#Override
int calculate()
{
return x + 6;
}
in class A still, which is incrementing the instance variable int x = 2 in class A . this variable overwrote the one in class B
Hence 2+6 = 8
We got the following exercice in our last exam, and I don't understand the right answers except the 1st one.
Here is it:
public class Gran {
private int x;
public Gran() { this.x = 68; }
public int age() { this.x = this.x+1; return this.x; }
#Override
public String toString() { return "Gran " + age(); }
}
public class Dad extends Gran {
private int x;
public Dad() { this.x = 41; }
#Override
public String toString() { return "Dad " + age(); }
}
public class Bro extends Dad {
private int x;
public Bro() { this.x = 21; }
#Override
public int age() { System.out.print("Bro "); return x; }
}
public class Sis extends Dad {
private int x;
public Sis() { this.x = 17; }
#Override
public int age() { System.out.print("Sis "); return super.age() - x; }
#Override
public String toString() { return "Sis " + super.toString(); }
}
What would be the correct print-outs if we call this:
Gran[] family = new Gran[] {new Gran(), new Dad(), new Bro(), new Sis()};
for (Gran member : family) System.out.println(member.toString());
It would be really helpful for me, if you tell me the logic behind the right answers.. I got really confused when I checked them!
You should check out the spec.
Especially Example 8.4.8.1-1. Overriding:
class Point {
int x = 0, y = 0;
void move(int dx, int dy) { x += dx; y += dy; }
}
class SlowPoint extends Point {
int xLimit, yLimit;
void move(int dx, int dy) {
super.move(limit(dx, xLimit), limit(dy, yLimit));
}
static int limit(int d, int limit) {
return d > limit ? limit : d < -limit ? -limit : d;
}
}
The caption says:
Here, the class SlowPoint overrides the declarations of method move of class Point with its own move method, which limits the distance that the point can move on each invocation of the method. When the move method is invoked for an instance of class SlowPoint, the overriding definition in class SlowPoint will always be called, even if the reference to the SlowPoint object is taken from a variable whose type is Point.
So with that in consideration, lets look at your example.
The hierarchy is:
Dad is a Gran
Bro is a Dad
Sis is a Dad
The declared type of all of the objects is Gran because of the line Gran[] family = new Gran[] {new Gran(), new Dad(), new Bro(), new Sis()}; That is the same as saying that the reference to each of the objects in the array are taken from a variable whose type is Gran.
Now you will call toString() on each of the elements in the family array. The first is Gran.toString(). When that object was created its x variable was initialized to 68. So the Gran.toString() method will build a String that is first "Gran" then call the age() method which increments x by one then returns the value of x which is 69 at this point. The + operator implicitly creates a new String that coerces the int to a String giving a String "Gran 69".
Next Dad.toString is very similar to Gran. Notice that it starts with the String "Dad" then calls age() which is inherited from Gran. So the output should be "Dad 69". The trick here is that the x variable is private scope, so the x in Dad is a different x then in Gran. That is the same for all of the classes.
For Bro, this class is a Dad, and Dad is a Gran. There is no overridden toString here so Dad.toString() gets used. That makes a String "Dad" then calls Bro.age() this prints "Bro" then returns the x from Bro to create a new String "Dad 21". The line is will look like "Bro Dad 21" because the print of "Bro" happens before the print of "Dad 21".
As for Sis this one is the toughest one. You should take everything from above and convince your self of how Overriding and scoping works. Good luck! I hope this helps.
The equals() method should check if the dimensions of the first box and the cube are the same. How to fix it? It currently does not work.
The program returns the message "illegal start of type" at if. I am new to this plz help
public class testNew
{
public static void main (String []args)
{
Rectangle3 one = new Rectangle3(5,20);
Box3 two = new Box3(4,4,4);
Box3 three = new Box3(4,10,5);
Cube3 four = new Cube3(4,4,4);
showEffectBoth(one);
showEffectBoth(two);
showEffectBoth(three);
showEffectBoth(four);
}
public static String showEffectBoth(Rectangle3 r)
{
return System.out.println(r);
}
boolean b = two.equals(four);
if (b == true)
{
System.out.println("Box and cube have the same dimensions");
}
}
public class Rectangle3
{
// instance variables
int length;
int width;
public Rectangle3(int l, int w)
{
length = l;
width = w;
}
public int getLength()
{
return length;
}
public int getWidth()
{
return width;
}
public String toString()
{
return getClass().getName() + " - " + length + " X " + width;
}
public boolean equals(Rectangle3 obj)
{
if ((getLength().equals(obj.getLength()) && getWidth().equals(obj.getWidth())))
return true;
else
return false;
}
}
First, regarding the compiler error you have, it has nothing to do with the equals() method. It's only because all of the code below, should be inside your main method as it's the only part where you are declaring the variablestwo and four:
boolean b = two.equals(four);
if (b == true) {
System.out.println("Box and cube have the same dimensions");
}
Notice also, that the Rectangle3 class shouldn't be in the same file as testNew as both are declared public, if you want to use both of them in the same file then you need to remove the public declration from one of them (the one you will not use as filename)
Second, your equals() method is technically correct (I guess functionally as well) but it's not the equals() method you included in your code here, because this one belong to Rectangle3 while the equals() you are testing here should be defined in Box3 and Cube3
NB: Please notice as per assylias's comment, that because b is a boolean there is no need to use if (b == true), just if (b) will be sufficient
It is not the equals function. The line
boolean b = two.equals(four)
Is illegal. It is not within any method and it references variables declared in main()!
I was doing some RnD I came across this this difference
my java code is as below
public class Main {
public static void main(String[] args) {
Integer x = 10;
increment(x);
System.out.println("print x" + x);
List<String> strList = new ArrayList<String>();
strList.add("one");
strList.add("two");
strList.add("three");
strList.add("four");
strList.add("five");
strList.add("six");
System.out.println("Before removing");
for (String string : strList) {
System.out.println("item " + string);
}
removeSomeItem(strList);
System.out.println("After removing");
for (String string : strList) {
System.out.println("item " + string);
}
}
private static void removeSomeItem(List<String> strList) {
strList.remove(0);
strList.remove(4);
}
private static void increment(Integer x) {
x++;
}
}
I got out for the above code as below
print x10
Before removing
item one
item two
item three
item four
item five
item six
After removing
item two
item three
item four
item five
my question is when I had sent Integer to function it behaved like value same way when I had sent List<String> its behaving like reference why is this difference ?
can any one explain
The main difference is that the Integer class is immutable, hence why you do not see the change in your main method.
x++; // this will simply return a new Integer
To see the difference, try this from your main method:
x = increment(x);
and in the increment method, change it to this:
return x++;
However, with your list example, you are simply passing a copy of the reference to the list. As long as that reference is not set to a new object (which it isn't), it is able to update the original list you passed.
This is exactly what happened
private static Integer b;
public static void main(String[] args) {
Integer x0 = 10;
b = x0;
increment(x0);
}
private static void increment(Integer x1) {
//x1 == b is true
x1++; //implies x1 = x1 + 1;
//x1 == b is now false
//at the end of the day, you've done nothing to x0 or b
}
EDIT: This code will fail because apparently, the JVM is caching Integer values between -128 and 127, see here, set x0 = 150 and test.
public class Main {
static Integer b;
public static void main(String[] args) {
Integer x = 150;
b = x;
increment(x);
}
private static void increment(Integer x) {
System.out.println(x == b); //true
x++;
System.out.println(x == b); //false
b++;
System.out.println(x == b); //false
}
}
Well in case of,
removeSomeItem(strList);
you are passing the address of original ArrayList to the method so when it remove some value using that reference the original ArrayList change too (actually they are single object with two access point , I mean the reference ).
But in case of Integer you also pass the reference and the increment(Integer x) method receive the original reference. But as Integer immutable when I do something like,
x++;
In the background its work like
x=new Integer(x+1);
That’s why the original Integer remain unchanged when the ArrayList change.
I have written a piece of code :
public class Child{
int y ;
private static final int z = getZ();
static {
System.out.println("The value of z is "+z);
}
public int getX(){
System.out.println("get x");
return 10;
}
public int getY(){
Child ch = new Child();
System.out.println("get y");
ch.y = getX();
return y;
}
public static int getZ(){
System.out.println("get z");
return new Child().getY();
}
public Child(){
System.out.println("Child constructor");
}
public static void main(String...args){
Child ch = new Child();
System.out.println("the value of z in main is "+z);
}
}
And the output is :
get z
Child constructor
Child constructor
get y
get x
The value of z is 0
Child constructor
the value of z in main is 0
Can anyone please explain me why the value of z is 0 and not 10 ?
EDIT:- Thanks everyone , I got the answer to my first question . I still have a doubt , as far as I know the static blocks are executed after the class is loaded and before the first object of the class is instantiated . Well then the SOP("The value of z is "+z) should have been executed before SOP("Child constructor") ! Ain't it ?
Look at getY():
public int getY(){
Child ch = new Child();
System.out.println("get y");
ch.y = getX();
return y;
}
The first three lines are irrelevant - they don't change the value of y in this instance, which is what gets returned.
You're creating an awful lot of pointless objects in frankly spaghetti code, called while initializing the same class that you're constructing instances of. I suggest you try to keep your code a lot simpler than this. Static initializers should be avoided where possible to start with, let alone ones that go all round the houses to do no useful work.
because getY() sets ch.y to 10, but returns the value of this.y.
In GetY you return this.y which never gets set.
On getY() you returned the uninitialized y variable instead of the Child ch instance.
Its because inside getY() method you are constructing a new CHild object and you are assigning 10 to that instance of variable y and when you return y that will be the current instance variable y.
I hope it explains .
To your second point, static fields and static blocks are initialized / executed in textual order.
Eg:
public class StaticTest()
{
static
{
System.out.println("s1 in block 1 :" + s1);
}
private static String s1 = "s1";
static
{
System.out.println("s1 in block 2 : " + s1);
}
public static void main(String args[])
{
new StaticTest();
}
}
The output of this will be -
s1 in block 1 :
s1 in block 2 : s1