views:

148

answers:

10

Is there a way for a Java class to have an awareness of its instantiator? For example:

public class Foo() {

    public Foo() {
        // can I get Bar.myInteger from here somehow 
        // without passing it in to the constructor?
    }
}

public class Bar {
    private int myInteger;

    public Bar() {
        myInteger = 0;

        Foo foo = new Foo();
    }
}
+2  A: 

No, you can't.

What are you trying to do?

SLaks
+1 for the second part.
Joachim Sauer
Just trying to make some code look a little prettier. It's going to be distributed so I want it to be easy to use and pretty syntactically. It's already pretty heavy on reflection, so I figured that if I had to add a little more it wouldn't be a big deal, but I also figure that it's not even possible to do what I'm asking.
Michael Pardo
Why was this downvoted?
SLaks
I think you should have commented instead of answered, this is not a real answer
Valentin Rocher
@Valentin: The answer is no.
SLaks
A: 

If they're in the same package, you can change the access level of myInteger to protected and Foo can access it directly, but you still need a reference to Bar unless myInteger is also static. I don't like to do that though, it makes them harder to test.

Aside from that, your options are using setters after instantiating the Foo or passing it to the constructor.

Jonathon
+1  A: 

You can get some information with a stack trace:

Throwable t = new Throwable();
t.fillInStackTrace();
StackTraceElement[] stt = t.getStackTrace();

then explore the elements of stt[].

Thomas Pornin
But you cannot get the class instance.
SLaks
You can't even find out the instance, you can only find out from which class you were called. And even that's a hack.
Joachim Sauer
@Joachim Sauer: If it's documented, it's definitely NOT a hack. Its use is acceptable in some sort of framework. But I'm very much in doubt that the person who asks this question needs something that sophisticated
zakovyrya
@zakovyrya I've actually tried this approach before, but like SLaks said, you can't get the class instance. This is would be part of a framework if it worked.
Michael Pardo
@zakovyrya: changing the behaviour of your code depending on the class that called you is most definitely a hack, even if it can be achieved using fully-documented and public APIs. Not everything that can be achieved with the public APIs is necessarily A Good Thing (tm).
Joachim Sauer
@Michael Pardo: So, maybe you should use something more capable than plain Java? Clojure or Scala?
zakovyrya
A: 

You can only access a private member of another class if you either explicitly pass it to the constructor if you provide getter/setter functions. So the answer to your question is no.

Chinmay Kanchi
A: 

You could force "Instantiators" to use a Factory. But in any case, the "identity" of the object requesting a new instance should be passed as a parameter.

And careful in defining what kind of identity you want to trace. An instance ID? a Class ID?

p.marino
+7  A: 

Is there any particular reason you don't want to pass anything in the constructor?

Simply put, this violates the encapsulation principle... and probably several others as well.

R. Bemrose
+2  A: 

You cannot access it the way you want to. But using an inner class might be appropriate here, depending on what problem you are trying to solve. The inner class can access private variables of the outer one.

waxwing
+5  A: 

With inner classes, you can.

public class Bar {

   private int myInteger;

   public class Foo() {

        public Foo() {
             // you can access myInteger
        }
    }


    public Bar() {
        myInteger = 0;
        Foo foo = new Foo();
    }
}
ewernli
+1 for second-guessing the question.
SLaks
A: 

If Foo were an inner class to Bar, it could see Bar's members.

Jim Kiley
A: 
elou