4

From the Eclipse Java compiler setting: Method does not override package visible method

"A package default method is not visible in a different package, and thus cannot be overridden. When this option is enabled, the compiler will signal such scenario either as an error or a warning."

How can I trigger this Warning/Error? I'm looking for a code example.

Eric the Red
  • 5,364
  • 11
  • 49
  • 63

4 Answers4

6

Foo.java:

package foopackage;

public class Foo {
    String getString() {
        return "foo";
    }
}

Bar.java:

package barpackage;

import foopackage.Foo;

public class Bar extends Foo {
    String getString() {
        return "bar";
    }
}

Should do it.

From the Eclipse Help docs:

A package default method is not visible in a different package, and thus cannot be overridden. When this option is enabled, the compiler will signal such scenario either as an error or a warning.

Matt Ball
  • 354,903
  • 100
  • 647
  • 710
  • I wrote an equivalent test and it gave `method does not override or implement a method from a supertype` on the `@Override` line (at least with Sun javac 1.6.0_22). Removing the `@Override` annotation makes the example compile. Your example needs imports btw. – sjr Feb 21 '11 at 19:06
  • 1
    @sjr Dont't put the annotation in and you'll get this error/warning instead. This is also a good example why using the `@Override` annotation is a good idea. – biziclop Feb 21 '11 at 19:08
  • Did you test this? What javac version are you using? I don't get this behaviour: removing the annotation causes the example to compile. – sjr Feb 21 '11 at 19:10
  • @sjr: yeah, I wasn't doing this in an IDE or anything. Thanks. – Matt Ball Feb 21 '11 at 19:11
  • @sjr: it's all about your compiler settings, specifically using Eclipse's compiler, and **not javac.** – Matt Ball Feb 21 '11 at 19:11
  • 1
    Oh yea, @Override should always be used when it is valid to do so. :) – sjr Feb 21 '11 at 19:12
0
package b;

public class Foo {

    void test() {}

}

And

package a;

import b.Foo;

public class Bar extends Foo {

    void test() {}
}
biziclop
  • 48,926
  • 12
  • 77
  • 104
0
package a;

public class A {
    // package protected method foo : no visibility modifier
    void foo() {
    }
}

package b;

public class B extends A {
    // although this method has the same signature as A.foo(), it doesn't 
    // override it because A.foo is not visible to B (other package)
    void foo() {
    }
}
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
0

An example of why this warning or error is important consider the following example:

package a;

public class Animal { 

    // Note: no visibility modifier therefore package-private
    String makeNoise() {
        return "no noise defined";
    }
}

package b;

import a.Animal;

public class Cat extends Animal {

    // Note: Eclipse will show the warning that it doesn't override
    public String makeNoise() {
        return "meow";
    }

}

package b;

import a.Animal;

public class Dog extends Animal {

    // Note: Eclipse will show the warning that it doesn't override
    public String makeNoise() {
        return "bark";
    }

}

package a;

import java.util.ArrayList;
import java.util.List;

import b.Cat;
import b.Dog;

public class Main {

    public static void main(String[] args) {
        // Make a list of Animals
        List<Animal> animals = new ArrayList<>();
        animals.add(new Cat());
        animals.add(new Dog());

        // Loop through the animals making their noises
        for (Animal animal : animals) {
            System.out.println(animal.makeNoise());
        }
    }

}

Copy paste the whole thing into Eclipse and it will sort out the classes and packages. Then run the Main class. You might expect it to print

meow
bark

But instead it prints

no noise defined
no noise defined

This is confusing behaviour which unexpectedly breaks polymorphism. The reason it does this is the Animal subclasses Cat and Dog have not actually overridden the method makeNoise at all, so when makeNoise is called on an Animal it uses the Animal implementation.

To fix this code add public or protected modifiers to the Animal makeNoise method, then rerun the code it will now work as expected. In this simple example its quite clear what is going on, but in a more complicated situation this behaviour could be extremely confusing and probably incorrect so the warning should be taken seriously.

James Mudd
  • 1,816
  • 1
  • 20
  • 25