web-dev-qa-db-fra.com

Pourquoi ne puis-je pas utiliser des constructeurs protégés en dehors du package?

Pourquoi ne puis-je pas utiliser des constructeurs protégés en dehors du package pour ce morceau de code:

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. Pourquoi est-ce que j'obtiens l'erreur même si j'ai étendu la classe? S'il vous plaît, expliquez

MODIFIER:

Erreur de compilation:

Le constructeur Example () n'est pas visible

35
Abhilash28

le modificateur protégé est utilisé uniquement avec dans le package et dans les sous-classes en dehors du package. Lorsque vous créez un objet à l'aide de Example ex=new Example();, il appellera le constructeur de classe parent par défaut.

En tant que constructeur de classe parent protégé, vous obtenez une erreur de compilation. Vous devez appeler le constructeur protégé conformément à JSL 6.6.2.2 comme indiqué ci-dessous dans l'exemple 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
    }
}

Exemple 2 conforme à 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 
    }
}
6
kittu

Généralement, protected signifie uniquement accessible aux sous-classes ou classes du même package. Cependant, voici les règles pour les constructeurs du JLS:

6.6.2.2. Accès qualifié à un constructeur protégé

Soit C la classe dans laquelle un constructeur protégé est déclaré et S la classe la plus interne dans la déclaration de laquelle l'utilisation du constructeur protégé se produit. Ensuite:

Si l'accès se fait par un super appel de constructeur de superclasse super (...) ou par un appel de constructeur de superclasse qualifié E.super (...), où E est une expression primaire, alors l'accès est autorisé.

Si l'accès se fait par une expression de création d'instance de classe anonyme new C (...) {...}, ou une expression de création d'instance de classe anonyme qualifiée E.new C (...) {...}, où E est une expression primaire, puis l'accès est autorisé.

Si l'accès se fait par une simple expression de création d'instance de classe new C (...), ou par une expression de création d'instance de classe qualifiée E.new C (...), où E est une expression primaire ou une expression de référence de méthode C: : new, où C est un ClassType, alors l'accès n'est pas autorisé. Un constructeur protégé est accessible par une expression de création d'instance de classe (qui ne déclare pas une classe anonyme) ou une expression de référence de méthode niquement à partir du package dans lequel il est défini.

Par exemple, cela ne compile pas

public class Example extends Exception {

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

mais cela ne

public class Example extends Exception {

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

et cela aussi

public class Example {

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

Les règles sont donc claires, mais je ne peux pas dire que je comprends les raisons derrière elles!

14
Paul Boddington

En fait, vous utilisez déjà le constructeur protégé de Example, car Check a un constructeur implicite et un appel de constructeur Example implicite:

public Check() {
    super();
}
3
Evgeniy Dorofeev