2015-04-09 12 views
16

Dlaczego nie mogę korzystać z chronionych konstruktorów poza pakietem dla tego kawałka kodu:Dlaczego nie mogę używać chronionych konstruktorów poza pakietem?

package code; 
public class Example{ 
    protected Example(){} 
    ... 
} 

Check.java

package test; 
public class Check extends Example { 
    void m1() { 
    Example ex=new Example(); //compilation error 
    } 
} 
  1. Dlaczego pojawia się błąd chociaż mam przedłużony klasę? Proszę wyjaśnić

EDIT: Błąd

kompilacji:

The constructor Example() is not visible 
+0

Znajomość błędu kompilacji może być bardzo przydatna w diagnozowaniu problemu ... –

+0

Spójrz na ten http://stackoverflow.com/questions/5150748/protected-constructor-and-accessibility możesz użyć chronionego konstruktora superklasy w konstruktorze podklasy, ale nie w celu utworzenia instancji nadklasy w dowolnym miejscu. – redge

+0

Mniej więcej z tego samego powodu, dla którego nie można wykonać 'public class Example {protected int i;}/* w innym pakiecie: */public class Check extends Przykład {void m1 (Example ex) {ex.i = 2;} } ' – immibis

Odpowiedz

3

chroniony modyfikator jest używany wyłącznie w pakiecie i podklas poza pakietem. Gdy utworzysz obiekt przy użyciu Example ex=new Example();, będzie on wywoływał domyślnie konstruktor klasy nadrzędnej.

Konstrukcja konstruktora klasy nadrzędnej powoduje błąd w czasie kompilacji. Trzeba zadzwonić do chronionego konstruktora według JSL 6.6.2.2, jak pokazano poniżej w przykładzie 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 
    } 
} 

Przykład 2 zgodnego 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 
    } 
} 
+1

Nr' protected' może być używany w różnych pakietach. Musisz tylko rozszerzyć klasę. 'default' scope is * within a package *. ** Chroniony modyfikator określa, że ​​członek może być dostępny tylko w swoim pakiecie (jak w pakiecie-prywatny), a dodatkowo przez podklasę swojej klasy w innym pakiecie.** – TheLostMind

+2

Mimo to odpowiedź nie jest przekonująca, rozumiem, że wywoła ona constanceor klasy nadrzędnej, tj.> Example(), która jest chroniona, ale jak wiemy, możemy użyć chronionych modyfikatorów poza pakietem, jeśli rozszerzymy tę klasę, to dlaczego tak nie robi? t pracujesz tutaj w przypadku konstruktorów? – Abhilash28

+1

Dlaczego konieczne jest samodzielne wywoływanie konstruktora nadklasy? Masz bezpośredni dostęp do metod nadklasy, jeśli nie są one domyślne lub prywatne. –

3

W rzeczywistości już używasz chroniony konstruktor przykładu Sprawdź, ponieważ ma niejawny konstruktor i niejawny wywołanie konstruktora Przykład:

public Check() { 
    super(); 
} 
9

Zazwyczaj protected oznacza dostępne tylko t o podklas lub klasy w tym samym pakiecie. Jednak tutaj są zasady dla konstruktorów z 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.

Jako przykład, to nie skompilować

public class Example extends Exception { 

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

ale to robi

public class Example extends Exception { 

    Example() { 
     super("Hello", null, false, false); 
    } 
} 

i tak robi to

public class Example { 

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

Rządzenie es są jasne, ale nie mogę powiedzieć, że rozumiem powody stojące za nimi!

+0

nauczyłem się nowych rzeczy;) – kittu

+0

@kittu Ja też. Nie wiedziałem, że istnieją dziwne ograniczenia. –

Powiązane problemy