how to access the Objects initialized inside constructor(JAVA)? - java

I have demonstrated an example below for my questions.
class B {
int name;
public int getName() {
return name;
}
public void setName(int name) {
this.name = name;
}
}
class A {
public A() {
// initializing object B
B b = new B();
}
}
class MainClass {
public static void main(String[] args) {
A a = new A();
}
}
How I access the object of B in the Mainclass which is initialized inside the class A Constructor?

One way to achieve this would be to add a getter method inside your A class which exposes the instance of B:
public class A {
private B b;
public A() {
b = new B();
}
public B getB() {
return b;
}
}
Usage:
A a = new A();
B myB = a.getB();

How about
class A {
private B b;
public A() {
// initializing object B
b = new B();
}
public B getB () {
return b;
}
}
from mainClass
A a = new A();
B b = a.getB ();

Related

Is there a way for an object to reference itself inside its constructor in java?

The explanation is simpler with a code:
public class Main {
public static void main (String[] args) throws java.lang.Exception {
A newObjectA = new A(new B(newObjectA));
}
class A{
A(B b){
//constructor code...
}
}
class B{
A refernceToA;
B(A a){
this.refernceToA = a;
//constructor code...
}
}
}
For this I got the following error:
The local variable newObjectA may not have been initialized
My solution right now is to simply make 1 more method besides the constructor, e.g. setB(), but I would like to now if the is a way to overcome this.
No, it is not possible to call it before it gets declared, however like you said you could:
public static void main (String[] args) throws java.lang.Exception {
B newObjectB = new B();
A newObjectA = new A(newObjectB);
newObjectB.setA(newObjectA);
}
class A{
A(B b){
//constructor code...
}
}
class B{
A refernceToA;
public void setA(A a) {
this.refernceToA = a;
}
}
There is not a simple way to do it, because A hasn't been instantiated when the nested B is being instantiated.
A newObjectA = new A(new B());
can also be written as
B newObjectB = new B();
A newObjectA = new A(newObjectB);
One way to eliminate this circular class dependency might be by creating another class which depends on both A and B;
From this:
class Scratch {
public static void main(String[] args) {
}
class A {
B b;
A(B b) {
this.b = b;
}
void methodUsingBInstance() {
// ...
}
void someOtherMethod() {
// ...
}
}
class B {
A a;
B(A a) {
this.a = a;
}
void methodUsingAInstance() {
// ...
}
void someOtherMethod() {
// ...
}
}
}
to this:
class Scratch {
public static void main(String[] args) {
}
class A {
void someOtherMethod() {
// ...
}
}
class B {
void someOtherMethod() {
// ...
}
}
class C {
A a;
B b;
C(A a, B b) {
this.a = a;
this.b = b;
}
void methodUsingBInstance() {
// ...
}
void methodUsingAInstance() {
// ...
}
}
}

Solving a java riddle

I'm given class A and class C, and I'm supposed to write class B which makes the output of the main in class C always successful! .
Sine there is a random boolean variable, I get a good result only when it's false, when it's true I don't get an output.
I'm not allowed to make any changes in class A or C.
I understand that the problem is in the third if in class C, but what changes I can make in class B to prevent from getting into this if?
public class A {
public String foo(String s) {
return s;
}
}
public class B extends A {
public A getA(boolean flag){
A a = new A();
if (flag){
return(a);
}
else{
return (a);
}
}
}
package sw1.riddles.second;
import java.util.Random;
public class C {
public static void main(String[] args) {
String input = args[0];
B b = new B();
Random random = new Random();
boolean randomBool = random.nextBoolean();
A a = b.getA(randomBool);
if (randomBool) {
if (!input.equals(a.foo(input))) {
return;
}
} else {
if (!(input+input).equals(a.foo(input))) {
return;
}
}
System.out.println("success!");
}
}
The class B should be as follows:
public class B extends A{
public String foo(String s){
return s+s;
}
public A getA(boolean flag){
if (flag){
A a = new A();
return(a);
}
else{
B b = new B();
return (b);
}
}
}
maybe solution:
public class B extends A {
public A getA(boolean flag){
if (flag){ //true -> usual A with foo == input
return new A(); //or this
}
//false-> custom A with foo == input + input
return new A(){
#Override
public String foo(String s) {
return s+s;
}
};
}
}

calling an object instantiated in one class, from other classes in java program

I have three classes.
Class A extends jFrame (Which is the main user interface)
Class B extends jPanel (This one is called to appear inside of the main jFrame)
and Class C to do some file handling and processing.
What I am trying to do is have an object of Class C instantiated in Class A and calling it in Class B.
Here's some sample code:
Public Class A extends javax.swing.JFrame {
Public A(){
C ObjectOfC = new C();
B panelWithButtons = new B();
}
}
public Class B extends javax.swing.JPanel{
String s = ObjectOfC.getName();
}
public Class C{
String name;
public String getName(){
return this.name;
}
}
Is there anyway to get this done? or is it a lost cause?
There are a number of ways to do this, depending on what you are trying to accomplish. You probably want to build either a constructor or a method for B that takes object C as an argument.
Example:
Public Class A extends javax.swing.JFrame {
Public A(){
C objectOfC = new C();
B panelWithButtons = new B(objectOfC);
}
}
public Class B extends javax.swing.JPanel{
String s;
public B (C objectOfC) {
this.s = objectOfC.getName();
}
}
public Class C{
String name;
public String getName(){
return this.name;
}
}
A singleton example as per your comment:
Public Class A extends javax.swing.JFrame {
Public A(){
B panelWithButtons = new B();
}
}
public Class B extends javax.swing.JPanel{
String s;
objectOfC C = C.getInstance();
this.s = objectOfC.getName();
}
public class C {
private static String name;
private static final C INSTANCE = new C();
private C() {}
public static C getInstance() {
return INSTANCE;
}
public static String getName() {
return this.name;
}
}
A singleton example with changing variables (and errors removed from the original code.):
public class A extends javax.swing.JFrame {
public A() {
C objectOfC = C.getInstance();
objectOfC.setName("Bob");
B panelWithButtons = new B(objectOfC);
System.out.println("objectOfC_A:" + objectOfC.getName()); //return "George"
}
}
public class B extends javax.swing.JPanel {
public B (C objectOfC) {
C c2 = C.getInstance();
objectOfC.setName("Fred");
c2.setName("George");
System.out.println("objectOfC_B:" + objectOfC.getName()); //returns "George"
System.out.println("c2: " + c2.getName()); //returns "George"
}
}
public class C {
private static String name;
private static final C INSTANCE = new C();
private C() {}
public static C getInstance() {
return INSTANCE;
}
public String getName() {
return C.name;
}
public void setName (String name) {
C.name = name;
}
}
With this example you can call C.getInstance from any class and they will all be sharing the same instance. However, you must be careful with how you are going to access the object; there are plenty of tutorials out there about multithreading singletons which you will need to do if you plan on modifying data in the C instance from multiple objects at the same time.

How to create two objects that hold a reference to eachother?

class A {
B ob1 = new B();
}
class B {
A ob2 = new A();
}
class C {
A a = new A();
// I am getting a StackOverflowException here
}
I am getting a StackOverflowException on the line I commented on. How can I solve this?
Problem with your approach is that when you create instance of A, this instance have to create instance of B which also have to create instance of A which creates instance of B... and so on until stack will overflow.
Probably most intuitive way would to solve this problem with getters/setters like
class A{
private B b;
public void setB(B b) { this.b = b; }
public B getB() { return b; }
}
class B{
private A a;
public void setA(A a) { this.a = a; }
public A getA() { return a; }
}
class Demo {
public static void main(final String[] args) throws Exception {
A a = new A();
B b = new B();
//let them see each other
a.setB(b);
b.setA(a);
}
}
If you want the B object to hold a reference to the A object that created it, you want something like this:
class A {
B ob1 = new B(this);
}
class B {
A a;
public B(A a) {
this.a = a;
}
}
This will not result in a StackOverflow and B will know about A and A will know about B. What you were doing is creating an instance of A which created an instance of B which created an instance of A which created...

Java: how does a component know its owner

Suppose I have a class A and a class B.
public class A {
private B b;
public A() {
this.b = new B();
}
public B getB() {
return this.b;
}
}
public class B {
public String getSome() {
return "Get some!";
}
}
I know I can get B through A, because A has (or owns) B: new A().getB().
But if I have B, can I get A?
Sure, just add routine getA() in you class B, and change the line in your constructor to
public A() {
this.b = new B(this);
}
This of course assumes your class B has a constructor which accepts an A, e.g.,
public B(A a) {
this.a = a;
}
B needs an explicit reference to its owner:
public class B {
private final A owner;
public B(A owner) {
this.owner = owner;
}
public A getOwner() {
return owner;
}
}
And in A:
public A() {
b = new B(this);
}
Nope. There is no such thing as an 'owner' in Java. Any object can be referenced by any number of other objects.
If you need B to always be bound to an instance of A, make B an inner class of A:
class A {
B b = new B();
class B {
String getSome() {
// this will refer to the enclosing A
return A.this.toString();
}
}
}
An inner (non-static) class always has an implicit reference to the enclosing instance and cannot exist without it. In order to instantiate B from outside, you need a nasty syntax: B b = new A().new B();
No you cannot. B has no reference to A.
No.
Class a has reference to class B, but class B has no reference to class A. References are one way only.
No, that's not possible. You're looking for backreferences, but we have to create them in the code if needed.
If you want to collect all referencers to B, you could do this with a constructor or with a factory (pattern) that creates B's. I'll show the factory:
public class B {
private static Set<? extends Object> referencers = new HashSet<? extends Object>();
private B(){} // no public constructor
public static create(Object parent) {
// cooperative approach, the caller should pass "this"
referencers.add(parent);
}
public static remove(Object parent) {
referencers.remove(parent);
}
}
you can also use inner classes
package test;
public class A {
B b = null;
public B getB()
{
return b;
}
public class B {
public A getA()
{
return A.this;
}
}
public static void main(String[] args) {
B b = new A().new B();
}
}

Categories

Resources