Let's say I have two classes, A and B, in turn have some methods, something() and nothing() and an instance of B is created in A, as
public class A {
public A() {
B b = new B();
b.nothing();
}
public void something() {
...
}
}
A calling b.nothing() is all standard stuff, but is there any means which by instance b can call a.something(), assuming the instance of A is called a. If not, why is this conceptually wrong?
I don't think there's anything conceptually wrong with this.
However, for the mechanics to work, b needs to know which instance of A to call something() on. For this, either B's constructor, or its nothing() method, needs to take an A reference as an argument.
example 1:
public class B {
public void nothing(A a) {
...
a.something();
...
}
}
example 2:
public class B {
private final A a;
public B(A a) {
this.a = a;
}
public void nothing() {
...
this.a.something();
...
}
}
example 3:
There is a third way, applicable in some circumstances. If B is an inner class of A, it has an implicit reference to its associated instance of A.
public class A {
public void something() { ... }
public class B {
public void nothing() {
...
something();
...
}
}
}
is there any means which by instance b can call a.something()
You can't get hold of the caller in a method so, no, there's no way to do that.
If not, why is this conceptually wrong?
Two issues come to my mind immediately:
What would the type of the caller be? Since anyone could call b.nothing(), you can't assume more than that it's an Object which would result in lots of ugly down casts.
The implementation of b.nothing() shouldn't care about who's calling him. What happens if you refactor A and move the call to b.nothing() to some other class? It would be quite surprising if b.nothing() all of a sudden stopped working.
The only way b.nothing() can call a.something() is if you tell the instance of B about the instance of A. For example:
b.nothing(this);
where B.nothing looks like:
public void nothing(A a)
{
// Do other stuff
a.something();
}
Alternatively, you could pass in this in the constructor to B, which would keep hold of the reference:
B b = new B(this);
b.nothing();
Note that letting this escape during a constructor call is generally a bad idea - you're letting B.nothing() call A.something() on an object which isn't fully initialized yet - its constructor hasn't finished executing. That can lead to undesirable and hard-to-diagnose behaviour sometimes.
To do this, b would require a reference to a. There are two ways to provide that:
Pass such a reference in the constructor of B or give B an appropriate setter.
If B is an inner class of A, then it has such a reference implicitly.
Related
Given the following source and ouput:
Source:
public class A
{
public void foo()
{
bar();
}
public void bar()
{
System.out.println ("in A's bar() method");
}
}
public class B extends A
{
#Override
public void foo()
{
super.foo();
// Do some specialized B stuff
}
#Override
public void bar()
{
System.out.println ("in B's bar() method");
}
}
public class Main
{
public static void main (String... args)
{
B b = new B();
b.foo();
}
}
Output:
in B's bar() method
Can someone please explain to me how the JVM is smart enough to polymorphically call B's (as opposed to A's) bar() method in this situation? I'd like to know what kind of dynamic dispatch magic is going on behind the scenes here.
Update: In case I wasn't clear enough, I know basically WHAT is happening, I'm looking for specific details on HOW the JVM makes it happen under the hood. The answers so far are too simplistic.
Update 2: Maybe I wasn't clear enough. When b.foo() is called, then super.foo() is called, then bar() is called in class A's foo(). How does the bar() that is called when specifically invoking super.foo() not call class A's bar() method, since the super keyword explicitly specifies class A? What steps does the JVM have to go through to sort this out?
Also, does this mean it's a bad idea in general to call public methods from within their own class since they can be overridden in this way?
Java uses the object's type when invoking the methods.
A b = new B();
b.foo();
Let's say you used above code.
Here what will happen is you are creating an object of type B and assign it to a reference of type A. Since the object type is B, you'll invoke the method in class B.
Even if the constructor or method you're currently in is defined in a super-class, the object doesn't change type. It will still be an object of type B. This can be demonstrated by using the this keyword.
this refers to the current object. That is not the same as the class defining the current method or constructor.
Try typing the following into A's constructor or in the foo() method:
System.out.println(this.getClass());
The function call sequence is (from eclipse debug view):
1. B.foo() // super.foo()
2. B(A).foo() // bar()
3. B.bar()
After the thread calls super.foo(), the JVM will check if there's any implementation in B (since we still hold B.class in the stack), if there is, JVM will call it.
This feature is guaranteed by JVM implementation. It is not smart, it just be designed this way, just like C++'s virtual methods.
Hope it helps.
Is it possible in Java to invoke an overridable method in such a way that it always executes the "locally defined" version rather than an overridden version from a subclass? I.e. is there an analog to super that refers to this class, rather than the super class?
Let me give a code example to hopefully make it clear what I'm trying to do:
class A {
void foo() {
System.out.println("Foo from A");
}
void bar() {
foo(); // <-- This is the important line!
}
}
class B extends A {
#Override
void foo() {
System.out.println("Foo from B");
}
}
If I do new B().bar(), it will call the bar() method defined in A, which calls foo() as overridden in B to print "Foo from B".
Is there a way that I can force the bar() method to call the foo() method as defined in A rather than B? Just like I can use super.foo() in B to call the foo() method as defined in A? Unfortunately using this.foo() still calls the version of the subclass. Even something like ((A) this).foo() or A.this.foo() doesn't work.
Clearly, I could simply define a private or final version of foo() in A and call that instead. But I am hoping for a solution, where all I do is change the "important line" in the code sample above to a different way of invoking foo() to have it print "Foo from A", preferably without some trick like reflection.
Your object is a B. It isn't an A! Here's an example:
public class Apple {
public void printColor() {
System.out.println("I am red");
}
public void bar() {
printColor();
}
}
Then the subclass:
public class GrannySmithApple extends Apple {
public void printColor() {
System.out.println("I am green");
}
}
GrannySmithApples are green, always (unless they are rotten, but that's a whole other can of bananas)! Once you have a GrannySmithApple, it's not an Apple anymore, except in the sense that you can do all the same things with it that you could a regular Apple (printColor, eat, etc.) Make sense? And anything that hasn't changed between the conversion from regular Apple to GrannySmithApple is obviously still the same.
You can have an "internal" foo() in A that is called.
class A {
private void fooInternal() {
System.out.println("Foo from A");
}
void foo() {
fooInternal();
}
void bar() {
fooInternal();
}
}
class B extends A {
#Override
void foo() {
System.out.println("Foo from B");
}
}
new B().bar() will now print "Foo from A" while new B().foo() will print "Foo from B".
Either make your methods static (baadddddd), either change your design.
Indeed, it makes no sense to provide the default behavior for a subclass that it is defined to adapt itself to the concerned method.
As your foo() method seems to vary, you may implement a Strategy Pattern like this:
interface BarProcess{
void foo();
}
public class DefaultBarProcess implements BarProcess{
void foo() {
System.out.println("Foo from A");
}
}
public class AnotherBarProcess implements BarProcess{
void foo() {
System.out.println("Foo from B");
}
}
class A {
private BarProcess barProcess;
public A(Bar barProcess){
this.barProcess = barProcess;
}
void bar() {
barProcess.foo();
}
}
class B extends A { //deprecated! No need to exist
}
As far as I know, a B object will always call its own foo() method. With that said, B.foo() can be defined to call the superclass' foo() method. For example, you could define B as follows:
class B extends A {
#Override public void foo() {
super.foo();
}
}
And doing so will have B call foo from A. But doing so will have it always do so.
There is this Rule of Thumb:
In Inheritance the most specific version of the method for that class is called.
- So it will be always the foo() method of Class B that will be called, if its called on an instance of B.
- Still if you want the foo() method of Class A to be called using your above mentioned code then you will need the super keyword.
Eg:
class B extends A {
#Override
void foo() {
super.foo();
}
}
foo() always invokes instance method of the class used in new ... statement.
In short I think that the answer to your question is NO, it can't be done. It would prevent you from overriding parts of behaviour completely.
class A {
method1() {
...
method2();
...
}
class B extends A {
// You can override method2 here to change the behaviour of method1
// because it will call **your** version of method2
// You **don't** have to override method1 to achieve that
method2() {
...
}
}
this references "this object", not "this class".
That means if you have an object B that extends A, when it executes a method in the superclass A that mentions this, it will actually point to the instance of B, so will execute the method on B.
You can think of the method in A as a default method. If the method is overridden in your actual object B, then it will always be called instead.
I suggest you change your design and use composition instead of inheritance: that would ensure a clear separation of concern, and make your code a lot easier to understand and test.
As others have stated there is no direct way to do it but you might consider a variant of this construct:
void bar() {
ClassA self = new ClassA();
self.foo(); // <-- This is the important line!
}
Here is an example:
There are a basic class(A) which handles lots of different classes (lets say B,C,D all extending P). In class A I need to call a function like:
public void doSmth(P variable) {
B b = (B)variable;
b.getSomeImportantInfo();
}
For this I am trying to add an interface (I) and define B, C, D implement it.
The trouble is, that doSmth will work with all this classes (B,C,D) and I dont want all of them implement this interface. So I'm trying to do something like this:
public void doSmth(P variable) {
if(variable instanceof I) {
((I)variable).getSomeImportantInfo();
}
}
But this does not work, cause it says it cant cast variable to I.
How can I achieve needed behavior? Also, I can not modify P and make it implement I.
I think it too later, but:
public static boolean isImplementsInterface(Class interfaze, Class clazz) {
for (Class c : clazz.getInterfaces()) {
if (c.equals(interfaze)) {
return true;
}
}
return false;
}
public static void main(String[] args) {
System.out.println(isImplementsInterface(CharSequence.class, String.class));
}
I think you don't need to explicitly typecast the variable to I.
Once you checked if it is instance of 'I', directly call the method and let the program decide at runtime..which will be invoked depending upon the actual object, reference variable refers.
I have a number of classes, please allow me to introduce them and then ask my question at the end:
I have a container class which contains two objects in a composite relationship:
public class Container{
A a;
B b;
public someMethod(){
a.getC().myMethod(b);
}
}
A and B are superclasses (or Interfaces), with subtypes that can also be the type held in the composite relationship.
A contains a member of (interface) type C:
public class A{
C c;
}
public interface C{
public void myMethod(B b);
}
public class D implements C{
public void myMethod(B b){
//This code will modify the state of object b, in class Container.
b.changeState();
}
}
public class E implements C{
public void myMethod(B b){
//This code will modify the state of object b, in class Container.
b.changeState();
}
}
My problem is that I wish to modify the state of object b from a method starting in the container class, which eventually calls code down the hierarchy, to classes D and E- calling myMethod() via dynamic binding. I want to do this because I am going to use polymorphism to run the correct myMethod() (depending on whether the type of object is D or E) and I wish to do this, rather than write IF statements.
So my problem is that it seems very bad continually passing the instance of object b down the class hierarchy to myMethod, so that I can run b-specific code to modify the state of b. Is there anything else I can do to modify b from d and e (collectively known as c)?
I can get this to work using just interfaces but without using generics- but when I added generics i had problems with types and that made me start to think if my whole design was flawed?
EDIT: I could probably do this easily just by using IF statements- but I wanted an elegant solution using polymorphism of classes D and E.
First of all, if I understood your question correctly, no instance of B is being "passed down" in your code. Dynamic dispatch will simply cause the myMethod() implementation in the actual type of a to be called with an instance of B as argument.
While it may be tedious to have to write the argument explicitly every time you implement myMethod(), there's nothing wrong with it.
The alternative is to give each subclass/implementation of A an attribute of type B. In this case, however, you would have to pass your B instance down the chain of constructors to the class that actually has your B attribute.
Your code would become:
public class A{
C c;
public A(C c) {
this.c = c;
}
public interface C{
public void myMethod(B b);
}
public abstract class CC {
protected B b;
public CC(B b) {
this.b = b;
public class D extends CC implements C {
public D(B b) {
super(b);
}
public void myMethod(){
b.changeState();
}
}
public class E extends CC implements C {
public E(B b) {
super(b);
}
public void myMethod(){
b.changeState();
}
}
And then somewhere, e.g. in Container's constructor:
b = new B();
a = new A(new E(b));
You could pass the instance of B to the constructor of E. (or use a setter). That poses issues in itself, but at least it avoids having to pass B down every time you call myMethod(), which now needs no arguments.
e.g.
somewhere inside B
E myE = new E(this);
and, inside E
final B myB;
public E(B myHigherLevelThing) {
this.myB = myHigherLevelThing;
}
public void myMethod() {
myB.changeState();
}
Use the most general interface for the declarations, I'm a little confused about your full hierarchy so there may be room for improvement there...
Is it possible to return in a static method a class? I will explain...
I have:
public class A { public static void blah(){} }
public class B { }
I want to create a static method in B witch returns A. So you can do:
A.blah();
And
B.getA().blah();
This, without creating an instance of A. Just use it static methods.
Is this possible?
This is a rebuttal of #irreputable's answer:
public class B {
public static A getA(){ return null; }
}
B.getA().blah(); //works!
It "works", but probably not in the sense that you expect, and certainly not in a useful way. Let's break this down into two parts:
A a = B.getA();
a.blah();
The first statement is returning a (null in this case) instance of A, and the second statement is ignoring that instance and calling A.blah(). So, these statements are actually equivalent to
B.getA();
A.blah();
or (given that getA() is side-effect free), just plain
A.blah();
And here's an example which illustrates this more clearly:
public class A {
public static void blah() { System.err.println("I'm an A"); }
}
public class SubA extends A {
public static void blah() { System.err.println("I'm a SubA"); }
}
public class B {
public static A getA(){ return new SubA(); }
}
B.getA().blah(); //prints "I'm an A".
... and this (I hope) illustrates why this approach doesn't solve the OP's problem.
I'm going to guess that the reason you ask this is that you want B to return many different classes with different behaviours - not just A.
You probably want to use an interface for what you're doing instead.
interface IA {
void blah();
}
public class B {
IA getA1() {
return new IA {
void blah() {
...code...
}
}
}
IA getA2() {
...
}
IA getA3() {
...
}
}
myCallingMethod {
B.getA1().blah();
B.getA2().blah();
B.getA3().blah();
}
No this is not possible. You have two options:
B.getA() returns an instance of
A, and blah() will be a non-static
method.
Directly call A.blah().
People are saying it's impossible, and that's kind of true, but if you use the reflection API you can do something close to that.
Here's how you could do it.
You have a class that does this.
public class B {
Class a
public static Class getA(){
return a;
}
}
then to call blah you do:
try{
Method m = B.getA().getDeclaredMethod("blah");
m.invoke(null);//for a static method, you can invoke on null
}
Catch(Exception e){
// see documentation for list of exceptions
}
So, why would you want to do this? Well, if you do it this way you can change the class A at So getA() could return A, B, C or D, all with different blah() functions. I'm not really sure what purpose that would serve, but if you want to do it, you can.
see:
Class.getDeclaredMethod() and Method.invoke() for more info.
I haven't tried this, so you might need to do some tweaking.
No, this is not possible. You can only return a reference to an instance of a class. The closest you can get to this is to return a reference to a variable of type Class. The question is: why do you want this? What problem are you trying to solve? There may be a better solution.
Even if it would be possible, it won't be of much use. The call A.blah() doesn't create an instance of A. It's a static method with no need for an instance.
And you can't use interfaces to implement static methods. So what should it be good for?
If you don't want to have an instance of A, then let B call blah() directly. I.e.
class B {
void blah() {
A.blah();
}
}
public class B {
public static A getA(){ return null; }
}
B.getA().blah(); //works!
EDIT
It is true that it is equivalent to
B.getA();
A.blah();
Except they look quite different. Imagine you have a chain of these.
I checked out org.apache.commons.cli.OptionBuilder and personly I wouldn't do it that way, but the author has his case. The API is used only in the beginning of a program, in a single thread.
API designers sometimes have to make some magic moves, don't be too judgemental.
You can return a Method using reflection which you can invoke() later.
However, it sounds like you are trying to do something which should be done another way.
Why are you trying to do this?