What is the default access level for methods in a public abstract class in Java?

False, let's see with a quick example:

package apackage;

public abstract class AbstractFoo {

  //A method with default visibility
  abstract void bar();

}

A quick implementation :

public class Foo extends AbstractFoo {

  @Override
  void bar() {}
}

Now, in another package :

public static void main(String[] args) throws Exception{

  AbstractFoo something=new Foo();
  something.bar();//Compiler complains here

Compiler complains about visibility. So the default visibility for methods is package protected, even if the class is public abstract.


The Java Language Specification for Java 7 does not mention separate rules for abstract methods, as such an abstract method without a qualified access level is default aka package private, just like a normal method would have been.

See also 6.6.1. Determining Accessibility:

  • A member (class, interface, field, or method) of a reference (class, interface, or array) type or a constructor of a class type is accessible only if the type is accessible and the member or constructor is declared to permit access:

    • If the member or constructor is declared public, then access is permitted.
      All members of interfaces are implicitly public.
    • Otherwise, if the member or constructor is declared protected, then access is permitted only when one of the following is true:
      • Access to the member or constructor occurs from within the package containing the class in which the protected member or constructor is declared.
      • Access is correct as described in §6.6.2.
    • Otherwise, if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.
    • Otherwise, we say there is default access, which is permitted only when the access occurs from within the package in which the type is declared.

(emphasis mine)

Also note that the term 'default access' is equivalent to 'package private', the only 'exception' to this is method declarations in an interface, which simply are always public and therefor don't need to be prefixed.

Edit:

As adenoyelle indicates in his answer, you can override a 'default' abstract method in a different package (as required by the rules in JLS 8.4.3.1. abstract Methods), as such you could consider them to be protected, but a quick scan of the JLS doesn't seem to make this explicit.

Edit 2:

I just tested it. It is impossible to implement an abstract class that has a method with default access in a different package. It simply does not compile. This shows that the method has default (package private) access, not protected. It also indicates that 8.4.3.1 doesn't actually require that it is always possible to implement an abstract method, just that it excludes nonsensical options like private abstract void method()

For example compiling:

package example;

public abstract class AbstractTest {
    abstract void testMethod();
}

and

package example.sub;

import example.AbstractTest;

public class TestImpl extends AbstractTest {
    void testMethod() {
        //implemented
    }
}

Leads to compile error:

example\sub\TestImpl.java:8: error: TestImpl is not abstract and does not override abstract method testMethod() in AbstractTest
public class TestImpl extends AbstractTest {
       ^
1 error

Tags:

Java