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();
}
}
Related
i have class A containing an object from class B and i want to access the data in class A from within class B. is there a way to access integer variable 'a' from within class B?
public class A{
int a;
B b = new B();
}
public class B{
/*want to access integer variable 'a' in class A from here*/
}
Yes all you have to do is pass class A to class B and save it as a variable
public class A{
int myNumb = 5;
B b = new B(this);
}
public class B{
A a;
public B (A a){
this.a=a;
test();
}
public void test(){
System.out.println(a.myNumb);
}
}
However I would recomend using getter
public class A{
int myNumb = 5;
B b = new B(this);
public int getmyNumb(){
return myNumb;
}
}
public class B{
A a;
public B (A a){
this.a=a;
test();
}
public void test(){
System.out.println(a.getmyNumb());
}
}
Let's say I have classA and classB:
public class A {
private B b;
public A(String id){
this.b = new B(id);
}
public void doSomethingA(String id){
// do somethingA
}
}
public class B{
public B(String id){
// call anotherThing (id)
}
public void doSomethingB(){
//somethingB
}
}
now I want to test methods inside classA (with it's instance) but wanna mock classB
Mockito allows me to mock classB, but when I instantiate classA, the constructor calls classB (which I want to avoid)
Is there a way to mock only the constructor (either classA or classB) but not the other methods?
You may mock any B object but you don't want to.
You want to mock the B b field of the A class.
Which is different.
You have to refactor your design and do B instantiation a dependency and not an internal processing.
A simple way is passing directly the B variable instead of the String as parameter :
public class A {
private B b;
public A(B b){
this.b = b;
}
public void doSomethingA(String id){
// do somethingA
}
}
Now mocking is straight :
#Mock B b;
public void test(){
A a = new A(b);
}
An alternative way would be using a Function<String, B> .
public class A {
private B b;
public A(Function<String, B> bFunction, String id){
this.b = bFunction.apply(id);
}
public void doSomethingA(String id){
// do somethingA
}
}
Mocking becomes so :
#Mock B b;
public void test(){
A a = new A(s-> b, "anyValue");
}
And implementation code could instantiate A as :
A a = new A(B::new, "id");
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...
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);
Sorry for the bad title, but I couldn't think of a better one.
I'm having a class A and a class B which is kind of a sub class of A, like so:
(Is there actually a correct name for it? Isn't "sub class" reserved for inheritance?)
class A {
int i = 0;
class B {
int j = 1;
}
}
class Test {
public static void main() {
A a = new A();
B b = a.new B();
A c = ??? b ??? // get "a" back
}
}
From B every property of A can be accessed, therefore both, a.i and b.i, return 0. Now, I'm wondering whether it's somehow possible to retrieve the original object of type A out of b, as b contains everything that a contains? Simple casting apparently doesn't do the trick.
Second one:
class A {
void print() {
System.out.println("This is class A.");
}
class B {
void print() {
// <--- How to access print() of class A (like this.A.print() or smth)?
System.out.println("This is class B.");
}
}
}
You could alternatively also provide me with some good resources on this topic, as I've been too stupid to find a good one so far.
Thanks in advance. :)
There doesn't seem to be a way to access the outer class from outside. But you can do it like this:
class A {
int i = 0;
class B {
final A outer = A.this;
int j = 1;
}
}
class Test {
public static void main() {
A a = new A();
A.B b = a.new B();
A c = b.outer // get "a" back
}
}
ClassName.this will be the instance of the outerclass associated with the instance of an inner class.
You can access it with the ParentClass.this syntax from within the inner class.
e.g.
public class Outter
{
class Inner {
public Outter getOutter()
{
return Outter.this;
}
}
public Inner getInner(){
return new Inner();
}
}
class Runner{
public static void main(String[] args){
Outter out = new Outter();
Outter.Inner inner = out.getInner();
System.out.println(inner.getOutter().toString());
}
}
[Edit: My answer is appropriate for C# programmers, but I can't guarantee that its applicable to Java.]
B is an inner class, not a subclass of A. Additionally, B does not hold an instance of A, so your code as is cannot return any instance of A.
You need to restructure your classes as follows:
class A
{
public class B
{
public A Parent;
public B(A parent)
{
this.Parent = parent;
}
}
}
Now your B class has a field 'Parent' which returns its parent. You can use these classes as follows (this is C# syntax, because I don't know if Java has a different syntax for instantiating inner classes):
public static void Main(String[] args)
{
A parent = new A();
A.B child = new A.B(child);
A backToParent = child.Parent;
}
Of course, creating your B class in this way seems little funny: technically, you can pass in any parent. It would probably be better to rewrite your A class with a method which returns a B:
class A
{
public class B
{
public A Parent;
public B(A parent)
{
this.Parent = parent;
}
}
public B getChild()
{
return new B(this);
}
}
public static void Main(String[] args)
{
A parent = new A();
A.B child = A.getChild();
A backToParent = child.Parent;
}
this seemed to work for me
class A {
int i = 0;
class B {
int j = 1;
}
}
class Test {
public static void main() {
A a = new A();
A.B b = a.new B();
A c = (A)b.getClass().getDeclaredField("this$0").get(b);
}
}