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

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...

Related

Easymock call autowired object method

Let's say I have Following classes:
public class A {
#Autowired B b;
public void doSomething(){
b.doSomeThingElse();
}
#Component
#Autowired C c;
public class B {
public void doSomethingElse(){
c.doIt();
}
How can I test A when you know I want to mock c.doIt() but want to call b.doSomethingElse(); with EasyMock?
Thanks in advance
#Autowired is nice but tend to make us forget about how to test. Just add a setter for b and c.
C c = mock(C.class);
c.doIt();
replay(c);
B b = new B();
b.setC(c);
A a = new A();
a.setB(b);
a.doSomething();
verify(c);
Or use constructor injection.
C c = mock(C.class);
c.doIt();
replay(c);
B b = new B(c);
A a = new A(b);
a.doSomething();
verify(c);
In this case, your classes become:
public class A {
private B b;
public A(B b) { // Spring will autowired by magic when calling the constructor
this.b = b;
}
public void doSomething() {
b.doSomeThingElse();
}
}
#Component
public class B {
private C c;
public B(C c) {
this.c = c;
}
public void doSomethingElse(){
c.doIt();
}
}

Suppose there are 2 classes A and B, is it possible to create an object of A in B and of B in A?

Class A
{
B b1=new B();
}
Class B
{
A a1=new A();
}
I'm talking about something like this? Is it possible?
Yes, you can. The following compiles just fine:
class A {
B b1 = new B();
public A() {
System.out.println("A constructor");
}
}
class B {
A a1 = new A();
public B() {
System.out.println("B constructor");
}
}
public class HelloWorld {
public static void main(String []args) {
A a0 = new A();
System.out.println("Done");
}
}
However, as shown in the output, it's generally a bad idea:
Exception in thread "main" java.lang.StackOverflowError
at B.<init>(HelloWorld.java:8)
at A.<init>(HelloWorld.java:3)
at B.<init>(HelloWorld.java:8)
at A.<init>(HelloWorld.java:3)
at B.<init>(HelloWorld.java:8)
:
at A.<init>(HelloWorld.java:3)
at B.<init>(HelloWorld.java:8)
at A.<init>(HelloWorld.java:3)
at B.<init>(HelloWorld.java:8)
The fact that construction of an A tries to create a B, and construction of a B tries to create an A, means that you'll get caught in infinite regress, eventually running out of stack space.
You can safely have two objects refer to each other but it's generally done after the construction phase, something like:
class A {
B b;
public A() {
System.out.println("A constructor");
}
public void setOther(B bx) {
System.out.println("A linker");
b = bx;
}
}
class B {
A a;
public B() {
System.out.println("B constructor");
}
public void setOther(A ax) {
System.out.println("B linker");
a = ax;
}
}
public class HelloWorld{
public static void main(String []args){
A a0 = new A();
B b0 = new B();
a0.setOther(b0);
b0.setOther(a0);
System.out.println("Done");
}
}
The output of that shows:
A constructor
B constructor
A linker
B linker
Done

how to access the Objects initialized inside constructor(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 ();

How to initialize a circular dependency (final fields referencing each other)?

How do you initialize this:
class A {
final B b;
A(B b) {
this.b = b;
}
}
class B {
final A a;
B(A a) {
this.a = a;
}
}
DI framework, reflection, better design?
Motivation and a use case (added):
My particular use case is simplifying field access in A's and B's sub-classes. So I'm injecting them to shortly reference them by fields in the derived classes without a need to declare explicitly in each sub-class.
There is also a recommendation on DI that objects should better be immutable: Guice best practices and anti-patterns.
You could use a factory method
class A {
final B b;
A(B b) {
this.b = b;
}
}
abstract class B {
final A a;
B() {
this.a = constructA();
}
protected abstract A constructA();
}
public class C {
public static void main(String []args){
new B(){
protected A constructA(){
return new A(this);
}
};
}
}
Though it may look dirty, but I prefer to replace one of the final references with Supplier (like one in Guava or Java 8) like:
class A {
final Supplier<B> b;
A(Supplier<B> b) {
this.b = b;
}
// keeping this constructor just for usability's sake
A(B b) {
this.b = ofInstance(b); // using Guava's Suppliers.ofInstance here
}
}
class B {
final A a;
B(A a) {
this.a = a;
}
}
public static void main(String[] args) {
// using MutableSupplier.create() static factory method
MutableSupplier<B> bRef = create();
A a = new A(bRef);
B b = bRef.set(new B(a));
}
where MutableSupplier looks somehow like the following:
import com.google.common.base.Supplier;
public class MutableSupplier<T> implements Supplier<T> {
private boolean valueWasSet;
private T value;
private MutableSupplier() {
}
#Override
public T get() {
if (!valueWasSet) {
throw new NullPointerException("Value has not been set yet");
}
return value;
}
public T set(final T value) {
if (valueWasSet) {
throw new IllegalStateException("Value has already been set and should not be reset");
}
this.value = value;
this.valueWasSet = true;
return value;
}
public static <T> MutableSupplier<T> create() {
return new MutableSupplier<T>();
}
}
I know that MutableSupplier's mutability looks super-ugly for immutability enthusiasts but I found that using it is more or less acceptable in such cases :)
What you are having is a circular dependency. The only way I can think of is to not declare the fields as final and have your dependency injected using setter injection instead of constructor injection.
A a = new A();
B b = new B();
a.setB(b);
b.setA(a);

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