Java: Retrieve this for methods above in the stack - java

How would you get a reference to an executing class several stack frames above the current one? For example, if you have:
Class a {
foo() {
new b().bar();
}
}
Class b {
bar() {
...
}
}
Is there a way to get the value that would be retrieved by using 'this' in foo() while the thread is executing bar()?

No, you can't. In all the languages that use a stack that I know of, the contents of other stack frames are hidden from you. There are a few things you can do to get it, beyond the obvious passing it as a parameter. One of the aspect oriented frameworks might get you something. Also, you can get a bit of debugging info from Thread.getStackTrace().

As other people have said, you will want your lower method to be passed the higher method's class instance and get it that way.
e.g:
Class A {
foo() {
new b().bar(this);
}
}
Class B {
bar(A aInstance) {
...
}
}

You have three choices. You can pass the calling object into the bar method:
Class A {
foo() {
new B().bar(this);
}
}
Class B {
bar(A caller) {
...
}
}
Or you can make class B an inner class of class A:
Class A {
foo() {
new B().bar();
}
Class B {
bar() {
A caller=A.this;
...
}
}
}
If all you need is the Class rather than the object instance, you have a third choice. By using Thread.currentThread().getStackTrace(), you can get the qualified name of a class at an arbitrary point in the stack, and use reflection to obtain the class instance. But that is so horrible, you should either fix your design, or (if you are writing your own debugger or something similar) try a simpler project until you know enough about java to figure this kind of thing out for yourself...

this is always a reference to the current instance of the object. So any usage of this in foo() will return an instance of Class A.

I think that Java methods are generally not allowed to directly access the call stack.
From a security standpoint, you wouldn't want an API function potentially accessing the data of the caller.

Related

When to use an object to call a method?

I am confused on when to use an object to call a method. For instance, sometimes I have to do object.someMethod() and other times the method works when it is just called someMethod(). If anyone could clarify when I need to use an object and when I do not, that would be great!
When you are calling non-static class members, you always need to specify the instance. However, there is one short-cut if you are inside a member function: Instead of writing this.otherMethod(), you can omit the this. part and only write otherMethod(), as it will be implicitly assumed by the compiler. It is a common situation and readability is not hurt from omitting it:
class Foo {
public void someMethod() {
otherMethod(); // same as calling: this.otherMethod()
}
public void otherMethod() {
}
}
MyClass object = new MyClass();
object.someMethod();
MyClass object2 = new MyClass();
someMethod(); // ERROR: from the context, it is not clear which instance is meant:
// Do you mean object.someMethod() or object2.someMethod()?
Note that it only works for methods of the same class. If you call it from outside, it will be a compile error. In the example above, it is mandatory that you explicitly write object.someMethod() or object2.someMethod().

How to access base class method?

Simplified demo code to show my problem.
class Base {
public String toString() { return "Base"; }
};
class A extends Base {
public String toString() { return "A"; }
};
class Test {
public void test1() {
A a = new A();
Base b = (Base)a; // cast is fine, but b is the same instance as a
System.out.println(b.toString()); // want "Base", but get "A"
}
private String testB(Base b) {
return b.toString(); // this should return "Base"
}
public void test2() {
System.out.println( testB(new A()) ); // want "Base", but get "A"
}
};
I tried the cast approach (test1) , and the helper method (test2).
Up to now, I found to need a copy constructor for Base to create a real Base object.
Is there a method that does not need a duplicate object?
Some background info:
I get an instance of A, and I know its base class has a nice method, which I'd like to use instead of the overwritten version. I'd prefer to neither modify class A nor B (although a copy c'tor were a good enhancement anyway ;) )
From class A directly, you can use super.toString(); to execute toString() on Base.
However, from outside class A, you can't call the superclass implementation in this way, doing so would break encapsulation. If you want to expose the superclass implementation then you still can, but you have to provide a separate method on A that exposes it directly.
Even using a trivial reflection based approach, you still won't be able to access it:
If the underlying method is an instance method, it is invoked using dynamic method lookup
System.out.println(Base.class.getMethod("toString", null).invoke(new A(), null)); //Prints "A"
...and using MethodHandles.lookup().findSpecial won't work either from outside the child class, as that has to be invoked where you have private access (otherwise you'll just get an IllegalAccessException.)
I concede that there may well be some weird and wonderful way of doing it directly in Java that I haven't thought of without bytecode manipulation, but suffice to say even if you can do it that way, you certainly shouldn't for anything but a quirky technical demonstration.
You need to create the B instance(copy constructor), if you are using the A instance you will always get "A" no matter if you cast it or no.

call get methods for different classes behind one another

I have a class with name "ConstituentSet". it has one method namely "getNucleusInConstSet()" which the output will be from "Proposition" class . The new Class "Proposition" have another method namely "getProperty()". I want to know what is the Propertry of my "Proposition Nucleus" in class "ConstituentSet". but i do not know how can i do that.
I wrote as follow but It does not work. (ConstituentSet.getNucleusInConstSet()).getProperty())
public class ConstituentSet{
// Constructor
private Proposition nucleusInConstSet;
public Proposition getNucleusInConstSet() {
return nucleusInConstSet;
}
}
public class Proposition{
//Constructor
private Property property;
public Property getProperty() {
return this.type;
}
}
You have:
(ConstituentSet.getNucleusInConstSet()).getProperty()
But you need to call an instance of ConstituentSet
e.g.
ConstituentSet cs = new ConstituentSet();
cs.getNucleusInConstSet().getProperty();
Note that this idiom (chained method calls) can be a pain. If one of your methods returns null, it's difficult to understand which one it is (without using a debugger). Note also that invocations of the form a().b().c().d() are a subtle form of broken encapsulation (a reveals that it has a b, that reveals it has a c etc.)
if you type ((ConstituentSet.getNucleusInConstSet()).getProperty()) you are attempting to call a static method of ConstituentSet.
You need to instantiate it and then call on that object.
ConstituentSet anInstanceOf = new ConstituentSet();
anInstanceOf.getNucleusInConstSet()).getProperty());
This won't work:
ConstituentSet.getNucleusInConstSet().getProperty();
Because the getNucleusInConstSet() method is not static. You have to use an instance of ConstituentSet, something like this:
ConstituentSet cs = new ConstituentSet();
cs.getNucleusInConstSet().getProperty();
Of course, you have to make sure that nucleusInConstSet is not null, or you'll get a NullPointerException. Initialize its value in ConstituentSet's constructor or set it using setNucleusInConstSet().
Alternatively, you could make getNucleusInConstSet() static, but I don't think that's the right thing to do in this case (but we don't have enough information about the problem to say so).

Is there a standard class which wraps a reference and provides a getter and setter?

Sorry for the stupid question.
I'm very sure, that the Java API provides a class which wraps a reference,
and provides a getter and a setter to it.
class SomeWrapperClass<T> {
private T obj;
public T get(){ return obj; }
public void set(T obj){ this.obj=obj; }
}
Am I right? Is there something like this in the Java API?
Thank you.
Yes, I could write it y myself, but why should I mimic existing functionality?
EDIT: I wanted to use it for reference
parameters (like the ref keyword in C#), or more specific,
to be able to "write to method parameters" ;)
There is the AtomicReference class, which provides this. It exists mostly to ensure atomicity, especially with the getAndSet() and compareAndSet() methods, but I guess it does what you want.
When I started programming in Java after years of writing C++, I was concerned with the fact that I could not return multiple objects from a function.
It turned out that not only was it possible but it was also improving the design of my programs.
However, Java's implementation of CORBA uses single-element arrays to pass things by reference. This also works with basic types.
I'm not clear what this would be for, but you could use one of the subclasses of the Reference type. They set the reference in the constructor rather than setter.
It' worth pointing out that the Reference subclasses are primarily intended to facilitate garbage collection, for example when used in conjunction with WeakHashMap.
I'm tempted to ask why you'd want one of these, but I assume it's so you can return multiple objects from a function...
Whenever I've wanted to do that, I've used an array or a container object...
bool doStuff(int params, ... , SomeObject[] returnedObject)
{
returnedObject[0] = new SomeObject();
return true;
}
void main(String[] args)
{
SomeObject myObject;
SomeObject[1] myObjectRef = new SomeObject[1];
if(doStuff(..., myObjectRef))
{
myObject = myObjectRef[0];
//handle stuff
}
//could not initialize.
}
... good question, but have not come across it. I'd vote no.
.... hm, after some reflection, reflection might be what comes close to it:
http://java.sun.com/developer/technicalArticles/ALT/Reflection/
there is java.lang.ref.Reference, but it is immutable (setter is missing). The java.lang.ref documentation says:
Every reference object provides methods for getting and clearing the reference. Aside from the clearing operation reference objects are otherwise immutable, so no set operation is provided. A program may further subclass these subclasses, adding whatever fields and methods are required for its purposes, or it may use these subclasses without change.
EDIT
void refDemo(MyReference<String> changeMe) {
changeMe.set("I like changing!");
...
the caller:
String iWantToChange = "I'm like a woman";
Reference<String> ref = new MyReference<String>(iWantToChange)
refDemo(myRef);
ref.get();
I don't like it however, too much code. This kind of features must be supported at language level as in C#.
If you are trying to return multiple values from a function, I would create a Pair, Triple, &c class that acts like a tuple.
class Pair<A,B> {
A a;
B b;
public void Pair() { }
public void Pair(A a,B b) {
this.a=a;
this.b=b;
}
public void Pair( Pair<? extends A,? extends B> p) {
this.a=p.a;
this.b=p.b;
}
public void setFirst(A a) { this.a=a; }
public A getFirst() { return a; }
public void setSecond(B b) { this.b=b; }
public B getSecond() { return b; }
}
This would allow you to return 2 (techically infinite) return values
/* Reads a line from the provided input stream and returns the number of
* characters read and the line read.*/
public Pair<Integer,String> read(System.in) {
...
}
I think there is no Java API Class designed for your intent, i would also prefer your example (the Wrapper Class) then using this "array-trick" because you could insert later some guards or can check several thinks via aspects or reflection and you're able to add features which are cross-cutting-concerns functionality.
But be sure that's what you want to do! Maybe you could redesign and come to another solutions?

How to by-pass inheritance in java when invoking a method

class Super {
public void anotherMethod(String s) {
retValue(s)
}
public String retValue(String s) {
return "Super " + s;
}
}
class Sub extends Super {
public void anotherMethod(String s) {
retValue(s)
}
public String retValue(String s) {
return "Sub " + s;
}
}
if suppose in main,
Super s = new Sub();
s.anotherMethod("Test");
Output will be, Sub Test
Can you anyone help me in telling how to get output Super Test with the given sequences in main.
And let me explain why I want this, say I have a class which has method test() and it can be overriden by sub classes, in some cases I want the overriden test() and in some cases I want the test() of super class itself, there are many ways to do this, best suggestions will be helpful.
Why would you ever want to do that ??
The whole point of polymorphism is to call the right method without the need to know which kind of instance you've got ...
Whenever I find myself asking (or being asked) a question like this, I know, categorically, that I have made a mistake in my design and/or my object definitions. Go back to your object hierarchy and check, double-check and triple-check that every inheritance relationship represents an "IS-A", and not a "HAS-A" or something even weaker.
And let me explain why I want this,
say I have a class which has method
test() and it's can be overriden by
sub classes, some cases I want the
overriden test() and in some cases
test() of super class itself, there
are many ways to do this, it will be
helpful if anyone can be best
solution.
If your subclass overrides test(), then it overrides test() - this is the whole point of object inheritance. You just call methods on the object, which are dynamically resolved to the appropriate implementation based on the object's runtime class. That's the beauty of polymorphic typing, in fact, the caller doesn't have to know about any of this at all, and the subclasses determine how their behaviour differs from the superclass.
If you sometimes want it to act as its superclass method and sometimes want it to act as its subclass method, then you need to provide the context required to do this. You could either define two test-type methods; one which is never overridden and so always returns the superclass' behaviour (you can even mark the definition with final to ensure it's not overridden), and your normal one which is overridden as appropriate by the subclasses.
Alternatively, if there is some contextual information available, you can let the subclasses decide how to handle this; their implementation(s) could check some proeprty, for example, and based on that decide whether to call super.test() or proceed with their own overridden implementation.
Which one you choose depends on conceptually whether your main method (i.e. the caller), or the (sub)class objects themselves, are going to be in the best position to judge whether the superclass' method should be called or not.
But in no case can you override a method and expect it to magically sometimes not be overridden.
You would have to go the route of:
Super s = new Super();
s.anotherMethod("Test");
...but that will defeat the purpose of inheritance if you also need whatever Sub's got. You could hack it like below but this seems an unelegant way to do it.
class Sub extends Super {
public String anotherMethod( String s, boolean bSuper ) {
if( bSuper )
return super.retValue(s);
else
return retValue(s);
}
public String retValue(String s) {
return "Sub " + s;
}
}
From class Sub you can call super.anotherMethod("bla"), but you cannot access the method of the superclass in your main method - that would be against the whole idea of using subclasses.
The runtime type of s is Sub, so you're only ever calling methods on that class.
Whilst I agree with the other posters that this is not the best idea in the world, I believe it could be done with a little bit of tinkering.
If your child class was defined as:
class Sub extends Super {
public void anotherMethod(String s) {
retValue(s)
}
public void yetAnotherMethodString s) {
super.retValue(s)
}
public String retValue(String s) {
return "Sub " + s;
}
}
and then call this new method in your main you would be able to print out "Super Test".
Doesn't seem like a very good plan tho. If you want access to parent functionality from a child class then don't override your parent method, just write a new one!
I'm hesistant to post this as an answer, since the question is quite horrible - but static methods would do roughly what the OP seems to want. Specifically, they are resolved on the compile-time declared class of the variable, not on the class of the instance held within that variable at runtime.
So modifying the original example:
class Super {
public static void staticMethod(String s) {
System.out.println("Super " + s);
}
}
class Sub extends Super {
public static void staticMethod(String s) {
System.out.println("Sub " + s);
}
}
public static void main(String[] args) {
Super s = new Sub();
s.staticMethod("Test");
}
then main() will print out "Super test".
But still don't do this until you understand why you want to, and you recognise that you are introducing subclasses and then gratuitously working around the point of them being there. Most IDEs for example will flag the above example with lots of warnings, saying that you shouldn't call static methods on instance variables (i.e. prefer Super.staticMethod("Test") instead of s.staticMethod("Test")), for exactly this reason.
You cannot modify Sub or Super directly? If you could control what instance of Sub is used you could do something like:
Super sub = new Sub() {
#Override
public String retValue() {
// re-implement Super.retValue()
}
};
otherObject.use(sub);
Of course this requires you to have or be able to reproduce the source code of Super.retValue() and for this method not to use anything you can't access from an anonymous child. If the API is this badly designed though, you might do well to think about changing it out for something else.
Can you anyone help me in telling how
to get output "Super Test" with the
given sequences in main.
Don't overwrite anotherMethod() and retValue() in Sub in the first place.
In Sub.anotherMethod(), return super.retValue(s) instead of retValue(s).

Categories

Resources