4
    interface A
    {
        public void f();
        public void g();
    }


   class B implements A
   {
       public void f() 
       {
            System.out.println("B.f()");
       }
   }

   public class Main 
   {
       public static void main(String[] args) 
       {
            B tmp = new B();
            tmp.f();
            System.out.println("B.f()");
       }
   }

I don't implement all the method in the interface A in B and it has a error that

    The type B must implement the inherited abstract method A.g()

but why it can get the output that

    B.f()
    B.f()
CLS
  • 131
  • 9
  • This is impossible. I assume that you have an old `class B` in your classpath which was compiled against an old version of the `interface`. – Uwe Plonus Aug 05 '13 at 07:52
  • @UwePlonus it just a test that with one file in the project. – CLS Aug 05 '13 at 07:56
  • you didnt implement method `g()` that causes compile error, and very likly when you executing your class, its executing last successful compiled version – user902383 Aug 05 '13 at 08:57

2 Answers2

3

Eclipse allows you to run code with compile-time errors - after giving you a warning and offering you the option to back out (which you should normally take).

If you try to call tmp.g() you'll get an exception indicating a compile-time failure.

Occasionally it can be useful to run code which doesn't fully compile - particularly if the compile-time failure is unrelated to the code you actually wish to run, e.g. when unit testing - but I would be very careful about how you use this feature.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • What. That seems like a bit of nasty magic...any reason why Eclipse supports this? – nneonneo Aug 05 '13 at 07:53
  • Also, is this feature documented anywhere? – nneonneo Aug 05 '13 at 07:53
  • Also, also, this answer resolves [this other question](http://stackoverflow.com/questions/10546718/how-eclipse-execute-java-code-when-there-are-compile-errors), where nobody could quite figure out what was happening. – nneonneo Aug 05 '13 at 07:54
  • @nneonneo: Eclipse normally puts up a big dialog box warning you that this is the case. I can't remember ever doing this without being aware of it. – Jon Skeet Aug 05 '13 at 07:57
  • it's possible to disable that dialog box, e.g. by ticking the box when you first see it. After that, you'll never be prompted, and it'll be a bit mysterious when your code runs. – nneonneo Aug 05 '13 at 08:07
  • @nneonneo: Right - but you'd have to at least have taken action once. I think it's a bad idea to disable the box :) – Jon Skeet Aug 05 '13 at 08:27
  • I suspect that an unsuspecting user might not read the box thoroughly, think "I don't want to have to confirm every launch I do!", and happily check the box to disable the warning. Perhaps it should be harder to disable that warning (require they go into the preferences, perhaps). – nneonneo Aug 05 '13 at 08:29
  • @nneonneo: Yes, I'd agree with that - and it should probably be easier to re-enable it, too. (I always struggle to find ways of re-enabling disabled dialogs...) – Jon Skeet Aug 05 '13 at 08:34
2

Eclipse can "patch" around certain classes of compile errors, and run a program even if errors exist. Normally, you get a dialog box that says the following:

Errors exist in required project(s):

(project name)

Proceed with launch?

[X] Always launch without asking

If you select Proceed, or if you have disabled the dialog, Eclipse will proceed to fix the compile errors if possible. If you try to run code impacted by the compile error, you'll get a runtime exception.

In this case, Eclipse adds a dummy B.g() method containing just the following:

throw new java.lang.Error("Unresolved compilation problem: \n"
"The type B must implement the inherited abstract method A.g()");

By inserting this dummy method, the code will compile properly and it will run. If you never call B.g, then you'll never see this error.

nneonneo
  • 171,345
  • 36
  • 312
  • 383