Why cant i use protected constructors outside the package?

This question already has an answer here:

  • In Java, difference between package private, public, protected, and private 26 answers

  • protected modifier is used only with in the package and in sub-classes outside the package. When you create a object using Example ex=new Example(); it will call parent class constructor by default.

    As parent class constructor being protected you are getting a compile time error. You need to call the protected constructor according to JSL 6.6.2.2 as shown below in example 2.

    package Super;
    
    public class SuperConstructorCall {
    
        protected SuperConstructorCall() {
        }
    
    }
    
    package Child;
    
    import Super.SuperConstructorCall;
    
    public class ChildCall extends SuperConstructorCall
    {
    
        public static void main(String[] args) {
    
            SuperConstructorCall s = new SuperConstructorCall(); // Compile time error saying SuperConstructorCall() has protected access in SuperConstructorCall
        }
    }
    

    Example 2 conforming to JLS 6.6.2.2:

    package Super;
    
        public class SuperConstructorCall {
    
        protected SuperConstructorCall() {
        }
    
    }
    
    package Child;
    
    import Super.SuperConstructorCall;
    
    public class ChildCall extends SuperConstructorCall
    {
    
        public static void main(String[] args) {
    
            SuperConstructorCall s = new SuperConstructorCall(){}; // This will work as the access is by an anonymous class instance creation expression 
        }
    }
    

    Usually protected means only accessible to subclasses or classes in the same package. However here are the rules for constructors from the JLS:

    6.6.2.2. Qualified Access to a protected Constructor

    Let C be the class in which a protected constructor is declared and let S be the innermost class in whose declaration the use of the protected constructor occurs. Then:

    If the access is by a superclass constructor invocation super(...), or a qualified superclass constructor invocation E.super(...), where E is a Primary expression, then the access is permitted.

    If the access is by an anonymous class instance creation expression new C(...){...}, or a qualified anonymous class instance creation expression E.new C(...){...}, where E is a Primary expression, then the access is permitted.

    If the access is by a simple class instance creation expression new C(...), or a qualified class instance creation expression E.new C(...), where E is a Primary expression, or a method reference expression C :: new, where C is a ClassType, then the access is not permitted. A protected constructor can be accessed by a class instance creation expression (that does not declare an anonymous class) or a method reference expression only from within the package in which it is defined.

    As an example, this does not compile

    public class Example extends Exception {
    
        void method() {
            Exception e = new Exception("Hello", null, false, false);
        }
    }
    

    but this does

    public class Example extends Exception {
    
        Example() {
            super("Hello", null, false, false);
        }
    }
    

    and so does this

    public class Example {
    
        void method() {
            Exception e = new Exception("Hello", null, false, false) {};
        }
    }
    

    So the rules are clear, but I can't say I understand the reasons behind them!


    事实上,你已经使用了Example的受保护构造函数,因为Check有一个隐含的构造函数和隐式的构造函数调用:

    public Check() {
        super();
    }
    
    链接地址: http://www.djcxy.com/p/24054.html

    上一篇: 在Java中继承保护与公共

    下一篇: 为什么不能在包外使用受保护的构造函数?