RamValli
RamValli

Reputation: 4475

Overriding - reducing visibility of a method as private, eclipse error

public class First {
    public void methodOne() {
        System.out.println("in Parent methodOne");
    }

    public void methodTwo() {
        System.out.println("in Parent methodTwo");
    }
}

public class Second extends First{
    private void methodOne() {
        System.out.println("methodOne");
    }

    @Override
    public void methodTwo() {
        System.out.println("methodTwo");
    }

    public static void main(String[] args) {
        First first = new Second();
        first.methodOne();
    }
}

Here in the Second class , We have a private method "methodOne". This shows an error in eclipse as "Cannot reduce the visibility of the inherited method from First". I know this error is because overriding method should not reduce the visibility

Even though that it shows a compilation error, it executes fine and gives the output as in Parent methodOne. If it is a compilation error, why it is producing the output?

When i change the access specifier to protected, it gives the expected compilation error in the console!

Upvotes: 1

Views: 285

Answers (4)

rupesh_padhye
rupesh_padhye

Reputation: 1405

  • Eclipse has implemented its own compiler called as Eclipse Compiler for Java (ECJ) by following Java Language Specifications(JLS).
  • This compiler can create CLASS files even in presence of compilation errors. However, in the case of serious errors (for example, references to inconsistent binaries, most likely related to an invalid build path), the Java builder does not produce any CLASS files.

If you check Class Second using decompiler ,methodOne will be as below

          private void methodOne()
              {
                throw new Error("Unresolved compilation problem: \n\tCannot reduce the visibility of the inherited method from First\n");
              }

Since Reference is of parent class and method is visible ,the parent method gets called.

Eclipse compiler identifies methodOne is overridden method of parent and should follow overridden methods rules.

Java builder concepts -Eclipse

Upvotes: 2

tharindu_DG
tharindu_DG

Reputation: 9291

Yes, I could recreate the issue in Spring Tool Suite Version: 3.7.0.RELEASE. Although there is an error pending, when forced to run although there are errors, the in Parent methodOne output occurs. Eclipse may be ignoring the error code block, since it is forced to execute.

I executed the following code,

 class First {
    public void methodOne() {
        System.out.println("in Parent methodOne");
    }

    public void methodTwo() {
        System.out.println("in Parent methodTwo");
    }
}

 public class Second extends First{
//    private void methodOne() {
//        System.out.println("methodOne");
//    }

    @Override
    public void methodTwo() {
        System.out.println("methodTwo");
    }

    public static void main(String[] args) {
        First first = new Second();
        first.methodOne();
    }
}

and I got in Parent methodOne as the output.

In the code you're assigning the object to a reference of it's parent.

First first = new Second();

Since the class Second doesn't have a method as methodOne, the methodOne method in the First class is called.

Assume you declare the methodOne in the second as Public.

Then you would get methodOne as the output.

When overriding,

  • Access to static fields, instance fields and static methods depends on the class of reference variable and not the actual object to which the variable points to.
  • This is opposite of what happens in the case of instance methods.
    In case of instance methods, the method in the actual class of the object is called.

Consider the following example.

    class ABCD {
        int x = 10;
        static int y = 20;

        public String getName() {
            return "ABCD";
        }
    }

    class MNOP extends ABCD {
        int x = 30;
        static int y = 40;

        public String getName() {
            return "MNOP";
        }
    }

    public static void main(String[] args) {

      System.out.println(new MNOP().x + ", " + new MNOP().y);

      ABCD a = new MNOP();
      System.out.println(a.x); // 10
      System.out.println(a.y); // 20
      System.out.println(a.getName()); // MNOP
    }

Hope this helps.

Upvotes: 1

hinneLinks
hinneLinks

Reputation: 3736

I think thats the "magic" of the Eclipse Compiler, it tries to compile it anyway.

This Example runs fine, since at runtime, the buggy Method compileError never gets called:

public class EclispeCompilerErrorExample {
    public static void main(String[] args) {
        if(false) {
            compileError();
        }
        else {
            System.out.println("But run anyways");
        }
    }

    private static void compileError() {
        int i = "this wont comppile";
    }
}

Your example with private works, since your Method never get called (its a private Method, inaccessible for the First-Object-Reference), so the First.methodOne gets called. When its protected ists actually "reachable" for the code, and therefore throw an Exception.

Upvotes: 1

Rod Bate
Rod Bate

Reputation: 79

If u wanna override a method in the sub class,the scope of the specified method modifier in the sub class must greater than the base class. Just like ur programe,the method methodOne's modifier in the class Second must be public.

Upvotes: -2

Related Questions