In Java, what happens when you reference a private class in a Vector from outside the class?
Example:
public class A {
private class B {}
public Vector<B> vector = new Vector<B>();
public A() {
vector.add(new B());
}
}
public class C {
public C() {
A a = new A();
a.vector.get(0); // <- What does this return?
}
}
You can try this code:
public static void main(String[] args) {
A a = new A();
Object o = a.vector.get(0); // <- What does this return?
System.out.println(o.getClass());
}
The class is A$B, so it knows that B is an inner class of A.
But you cannot access any of the members of B. For example, if you change class A to this:
public class A {
private class B {
public int x;
}
public Vector<B> vector = new Vector<B>();
public A() {
vector.add(new B());
vector.get(0).x = 10;
}
}
You still won't be able to do this:
public static void main(String[] args) {
A a = new A();
System.out.println(a.vector.get(0).x); // this won't compile
}
It will say the type A.B is not visible.
It returns the reference to an Object of type A$B.
You will be able to assign it to an Object reference, e.g.
Object o = a.vector.get( 0 );
You can even use reflection to investigate properties of o.
Just a general reminder, please use java.util.ArrayList instead of Vector.
It will return an object of type A.B However you cannot do anything with it really because you will not be able to assign it to a variable or call any methods on it. If you do:
System.out.println(a.vector.get(0));
you will get something like:
A$B#42e816
Related
I just have learned java. I'm fiding the different between this both ways of creating an object
public class A {
}
public class B extends A {
}
public static void main(String[] args){
A object = new B();
B object = new B();
}
Lets understand it with the example below.
In class A we added a getMethodofA(). So creating reference variable as A or B does not matter. As A is super class getMethodofA() will be available for both the objects of Type A or Type B
In class B we added a getMethodofB(). So creating reference variable as A or B matters. If you create object with reference variable as A, then only getMethodofA() will be available. While If you create object with reference variable B both the methods will be visible getMethodofA() and getMethodofB()
public class A {
public void getMethodofA(){
System.out.println("I am method A")
}
}
public class B extends A {
public void getMethodofB(){
System.out.println("I am method B")
}
}
public static void main(String[] args){
A objectA = new B();
objectA.getMethodofA();//No error
objectA.getMethodofB();//Compile time error
B objectB = new B();
objectB.getMethodofA();//No error
objectB.getMethodofB();//No error
}
I have a class A and within class A I have function func1 and func2.
In the same file I have class B and in that class B I have function func3.
In the main class, an object obj1 of class A is declared.
With this object, func1 of class A is called.
Within func1 of class A, an object obj2 of class B is created.
With this object, func3 of class B is called.
Now within func3 of class B, i want call func2 of class A with the object obj1. For this I want to refer to that object from within func3 of class B. Is it possible? If yes, how?
I tried using this.this.func2 which wouldn't work.
For now I am passing the object obj1 as an argument and it works fine. But I want to do the same without passing it because I want to use an array of objects and every time the object should differ
class A {
int attr1, attr2;
public void func1() {
int attr1 = 3;
int attr2 = 6;
B obj2 = new B();
obj2.func3();
}
public void func2() {
this.attr1 = 5;
this.attr2 = 10;
}
}
class B {
int atr1, atr2;
public void func3() {
atr1 = 4;
atr2 = 8;
// here I want to access the object obj1 to call the function func2()
}
}
public class Main {
public static void main(String args[]) {
A obj1 = new A();
A.func1();
}
}
Is it possible?
Yes.
If yes, how?
Option 1: Pass as parameter
Pass obj1 as parameter to func3.
Or more precisely, since func3 is called from a method of obj1, pass this as the parameter value:
class A {
public void func1()
{
B obj2 = new B();
obj2.func3(this);
}
}
class B {
public void func3(A a)
{
a.func2();
}
}
Option 2: Pass to constructor
Pass the A reference to the B constructor, and have B remember it in a field.
class A {
public void func1()
{
B obj2 = new B(this);
obj2.func3();
}
}
class B {
A a;
public B(A a) {
this.a = a;
}
public void func3()
{
this.a.func2();
}
}
Option 3: Inner class
Make class B an inner class of A. Essentially the same as option 2, but the compiler handles the reference to A for you.
class A {
public void func1()
{
B obj2 = new B();
obj2.func3();
}
class B {
public void func3()
{
A.this.func2();
}
}
}
What I mean by this is, if I have A obj1 = new B(); A obj2 = new B(); I want to know how to call the same method for both objects, and also want to know how to know which object is calling the method and when:
For example, lets say my class hierarchy looks something like this:
abstract class A {
public void method_1() {
//Do something
}
}
class B extends A {
public boolean method_2(A obj) {
//Do something
}
}
If I where to do obj1.method_2(obj2); How do I, inside method_2(), when I code it so both obj1 and obj2 call method_1(), distinguish which obj is calling the method?
I hope my question was clear enough.
I'm sorry in advance if my English wasn't understandable enough.
obj1 which is instance of B but references class A, won't have access to method_2
So you need to cast like this
((B) obj1).method_2(obj2);
or you can change the reference to B instead of A
B obj1 = new B();
Base reference can't call the child's method.
public class Main {
public static void main(String arg[] ) {
A obj1 = new A() {};
A obj2 = new B();
B obj3 = new B();
obj1.method_1("1 "+obj1.getClass());
obj2.method_1("2 "+obj2.getClass());
obj3.method_1("3 "+obj3.getClass());
obj3.method_2(obj1);
obj3.method_2(obj2);
}
}
abstract class A {
public void method_1(String className) {//Do something
System.out.println("A.method_1() called by "+className);
}
}
class B extends A {
public boolean method_2(A obj) {//Do something
super.method_1("4 "+obj.getClass());
obj.method_1("5 "+obj.getClass());
return true;
}
}
You can NOT create an object of class A as its abstract class. However you can create object of B and pass it in place of A in method_2(). When you call method_1() inside method_2(), you are still calling it through object of class B. Here is the test program I could write based on my understanding of your question -
public class App {
public static void main(String[] args) {
B b = new B();
B b2 = new B();
b.method_2(b2); //Or
//b.method_2((A)b2);
}
}
abstract class A {
public void method_1() {
System.out.println("In method_1 = " + this.getClass());
}
}
class B extends A {
public boolean method_2(A a) {
System.out.println("In method_2 = " + this.getClass());
a.method_1();
return false;
}
}
The result is that both methods are called by object of class B. You can user getSuperClass() method to get superclass name.
I'm not novice in java, but I've got an example that made me confused.
Here it is:
class A {
public A() { System.out.print("O"); }
}
class B {
{ System.out.print("A"); }
public B() { System.out.print("D"); }
}
class C {
static { System.out.print("3"); }
public C() { System.out.print("P"); }
}
public class D extends C {
private A objA = new A();
private static B objB = new B();
public D() { System.out.print("T"); }
public static void main(String[] args){
new D();
}
}
So what is the result in system.out?
We know that static members are the first, so "3" will print first cause it is in the superclass and private static B objB = new B(); will initialize after it (instance initializer and then constructor).
We get 3AD in console.
Then the main method runs and create a new instance of class D, its ok.
But since this step the order is strange:
1 Constructor of the superclass public C() { System.out.print("P"); }
3ADP in console.
2 Then field of D.class private A objA = new A();
3ADPO in console.
3 And constructor of D.class is the last, so:
3ADPOT in console.
So the question is: why does superclass constructor run before field of subclass? I thought that constructors have lowest priority. Can anyone share a link on docs plz?
Simply if we think then its easy to understand that first the subclass inherits from the super class and then only can it override the behaviour or acess the properties defined in the super class.
Whenever we create an object of a class A , first it is checked if the class is loaded, if not then it is loaded which invokes its static initilizer if it is present, then all the static fields are initilized (with default value or the values defined). After this super constructor is called, all the properties as set by the super class are set. Then all the instance fields are initilized and then finally constructor code of A is executed.
Below is the execution ordering.
public class A{
static{
// 1
}
int x = 30; // 3
public A(){
//4
}
}
public class B extends A{
static{
//2
}
private int s = 60; //5
public B(){
//6
}
}
public class Test {
public static void main(String[] args){
new B();
}
}
public class B {
public static void main(String[] args) {
A a = new A();
}
}
public class A {
A b = new A();
}
Because every A creates an inner field named b of type A. That's infinitely recurisve, because to create a b you must also create an A (which adds another b). Because initializers are copied to the default constructor, your example is equivalent to something like,
public class A {
// A b=new A();
A b;
public A() {
super();
b = new A();
}
}
I dont understand your requirement. Why did you declare instance variable within same class. It will behave like a recursive loop. From the main method it will try to create the object of class A and during that object creation it will try to initialize the variable "a". As a result again it will create another instance of A and so on.