简体   繁体   中英

Failed to open implementation for method added to interface from base class in Eclipse

I'm using Eclipse Neon.

Basically I'm creating a new interface and adding to it an existing method found in different base class.

I have a class MyServiceImpl which extends base class GeneralServiceImpl with abstract method doB .

I created an interface GeneralService for GeneralServiceImpl and added also doB method:

public interface GeneralService {    
    abstract void doB();
}

public class GeneralServiceImpl implements GeneralService {
   @Override
   public void doB() { }
   }
}
@Service
public class MyServiceImpl extends GeneralServiceImpl implements MyService {
     @Override
     public void doC() { }
}

And my new interface include expecting to use GeneralServiceImpl method doB()

public interface MyService {
    public void doC();
    public void doB();
}

This works but in eclipse when I click on doB() method ( doC() works) in MyService Open Implementation ( Ctrl + Left mouse click) I can't find any implementation available (see below)

Is it Eclipse bug? Is my setting wrongly constructed? is my expectation wrong?

  • Note from GeneralService I can open implementation for its doB() method

  • Note another reason I need it is also to add a Spring Service support to existing method

Please see it is not a bug.

Lets understand (I have made pictorial representation to understand better):

在此输入图像描述

It is clear that the GeneralServiceImpl class overrides doB() function of implementing interface GeneralService as well as MyServiceImpl implements doC() function of its implementing interface MyService .

Also, there is inheritance relation between MyServiceImpl and GeneralServiceImpl --> MyServiceImpl extends GeneralServiceImpl , so MyServiceImpl has doB(){} .

Now we have to understand here that IDEs, completion and compiler use the static view.

If you want to know run time view then one have to use debugging mode.

So, if we see the way your classes and interface is designed there is no direct relation between MyService and GeneralServiceImpl , so eclipse is not aware of its runtime implementation and thus does not highlights the same.

Rather that dotted line in the diagram represents runtime relation and thus implementation of void doB(); function.


Adding more info based on @howlger comment :

For an Interface implementing class should override all the declared functions (unless abstract ). and as an IDE Eclipse when searching for an implementation of a function from Interface then it looks only for direct implementation in implementing classes. (like for doC() it works). [static view / compiler]

Now, imagine between MyServiceImpl & GeneralServiceImpl we have another class SubGeneralServiceImpl which also overrides doB() as

public class SubGeneralServiceImpl extends GeneralServiceImpl {
    public void doB() {
            //
        }
    }

and now MyServiceImpl extends SubGeneralServiceImpl and SubGeneralServiceImpl further extends GeneralServiceImpl .

So, even now MyServiceImpl has doB() but now access to 2 doB() implementation , which can be seen :

在此输入图像描述

thus in static view (compiler) it is absolutely fine as far as MyServiceImpl overrides doB() & doC() ...however Eclipse as an IDE is not sure which implementation is going to be used which comes at runtime, thus not able to give you the implementation of doB() when tried getting from MyService Interface.

Hope this helps.

It works for me.

Tested on:

Eclipse IDE for Enterprise Java Developers.

Version: 2019-03 (4.11.0) Build id: 20190314-1200

I also tested it on a fresh installation (no plugins other than the default) and it also works.

Also tested on OSX and Linux (no Windows available... sorry)

GeneralServiceImpl.doB() is not an implementation of MyService.doB() but in MyServiceImpl used to implement MyService.doB() . Therefore, it would be wrong to display GeneralServiceImpl.doB() as an implementation or definition of MyService.doB() .

In the following example, annotating FooImpl with @Override leads to a compile-time error. According to the Java Language Specification 9.6.4.4. this means FooImpl.foo() does not implement or define API.foo() :

class MyClass extends FooImpl implements API {
    @Override // <- correct
    public void bar() {};
}

interface API {
    void foo();
    void bar();
}

class FooImpl {
    // @Override <- compile error
    public void foo() {}
}

Please note that there are more possibilities for non-explicit implementation/definition of methods which will not shown by Eclipse: for example instrumentation via a Java agent (eg used to mock objects) or via a declarative framework.

  1. When you do

ctrl + mouse hover

, eclipse gives you 2 options:

a. Open declaration.

b. Open Implementation.

You need to select second option.

  1. I would prefer to use

'ctrl + T'

to see full implementation hierarchy.

Hope it helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM