views:

118

answers:

6

Consider

Class A has two constructors new A(int), new A(int, String)

also

it has a method show()

Then given a statement like,

A a1= new A(4);
A a2= new A(3, "foo");

and later in code (or in some methods where these object were passed)

a1.show();
a2.show();
new A(3).show();
and 
new A(2,"bar").show();

If I wanted to differentiate between these show methods based on the objects (a1 and a2) as well as based on class instance expression (calling show directly on constructors) and did not know which constructor was used (especially for the objects a1 and a2) how do I find that out--say reflectively?

A: 

It is not possible to determine by reflection which constructor was used to instantiate an object. Why not simply set an instance variable to a different value in each constructor to track which one was called?

Asaph
+1  A: 

The only way to do this would be to have each constructor set a different variable to indicate that it was used.

But I agree with Tom; this sounds like a bad idea. It shouldn't matter how you created an object (because a constructor may not even have been used at all, say, in serialisation), it should only matter that all it's properties (public or not) are set appropriately, to reflect the state it needs to be in.

Noon Silk
+1  A: 

Maybe A should be two different classes (each with a different constructor); or two different subclasses of a common base class: in that way, each class could have it's own distinct implementation of the show method.

Alternatively, have a data member inside A (perhaps a boolean, or the string) whose value is set differently by each constructor.

ChrisW
It may be important to note that the constructor may not always be called to create the object, so this solution won't work, in general.
Noon Silk
silky: How, pray-tell, do you create an object in Java without calling its constructor?
R. Bemrose
R: To be fair, when I commented on that the poster hadn't confirmed the language; I'm not a regular Java user, but I've been hinted to the fact that it is possible via `sun.misc.Unsafe`. Further research required; feel free to carry it out and report back :)
Noon Silk
+1  A: 

Agree that you're better off using two separate classes, in which case you could use polymorphism (example in C#),

public class Base
{
    public BaseClass()
    public virtual void Show
    {
        // show stuff
    }
}

public class A : Base
{
    public A(int i)
    public override void Show()
    {
        // show A stuff
    }
}

public class B : Base
{
    public B(int i, String s)
    public override void Show()
    {
        // show B stuff
    }
}

Then call the classes

Base a1= new A(4);
Base a2= new B(3, "foo");

and it should be easy to differentiate between these show methods based on the a1 and a2 objects.

Rafe Lavelle
+1  A: 

If two classes have different sets of behavior then they are two distinct classes. A single class should not behave differently based on how it was constructed.

John Saunders
A: 

So all four ways of calling show should perform a difference action?

Why and what is the difference between each of the actions?

Without knowing more we can only make wild guesses. It does sound like a job for two or maybe even four classes (plus an base class/interface) and a factory to create them.

If the question is purely theoretical - No, you can not tell at run time the difference between:

A a = new A();
a.show();

and

new A().show();

The only way to do so would be to exam the source¹, so you would have to include the source and compile with full source numbers included. The parse the source code to work out how it was called.

mlk