35 votes

Java: sélection entre constructeurs surchargés

Par cette question, Java, sélectionnez "plus spécifiques" option lorsque vous essayez de sélectionner entre ambigu constructeurs surchargés. Dans cet exemple:

public class Test{
    private Test(Map map){
        System.out.println("Map");
    }
    private Test(Object o){
        System.out.println("Object");
    }
    public static void main(String[] args){
        new Test(null);
    }
}

il apparaîtra à l'impression

"La carte"

Cependant, j'ai été à essayer de comprendre exactement ce que "plus spécifique" signifie. Je suppose qu'il voulait dire "le moins ambigu", comme dans "peut renvoyer au plus petit nombre possible de types." Dans ce contexte, Object peut être quelque chose qui n'est pas un primitif, tandis que d' Map ne peuvent être Map ou ? extends Map. En gros, je suppose que selon la classe était plus proche de la feuille de l'arbre d'héritage doit être sélectionné. Qui fonctionne quand une classe est une sous-classe de l'autre:

public class Test{
    private Test(A a){
        System.out.println("A");
    }
    private Test(B b){
        System.out.println("B");
    }
    public static void main(String[] args){
        new Test(null);
    }
}

class A{}

class B extends A{}

"B"

Puis je suis arrivé à ceci:

public class Test{
    private Test(A a){
        System.out.println("A");
    }
    private Test(E e){
        System.out.println("E");
    }
    public static void main(String[] args){
        new Test(null);
    }
}

class A{}

class B extends A{}

class C{}

class D extends C{}

class E extends D{}

Je pense qu'elle devrait imprimer E, comme E ne peuvent renvoyer qu'à un type connu, alors qu' A peut se référer à deux (A et B). Mais il donne une référence ambiguë d'erreur.

Comment est-il réellement le choix du constructeur? J'ai lu les docs mais franchement, je ne pouvais pas tout à fait suivi la façon dont il détermine la spécificité. J'espère pour une description de exactement pourquoi il ne peut pas déterminer qu' E plus précis que l' A.

45voto

Jon Skeet Points 692016

Elle n'est pas basée sur le nombre de types qui sont convertibles pour le type de paramètre - il si une valeur valide pour une surcharge est valable pour l'autre, en raison des conversions implicites.

Par exemple, il y a une conversion implicite de String de Object, mais l'inverse n'est pas vrai, alors String plus précis que l' Object.

De même, il y a une conversion implicite de B de A, mais l'inverse n'est pas vrai, alors B plus précis que l' A.

Avec A et E cependant, ce n'est plus spécifique que l'autre, il n'y pas de conversion de l' A de E, et pas de conversion de l' E de A. C'est pourquoi la résolution de surcharge échoue.

Le tbi pertinent de la JLS est en fait 15.12.2.5, qui comprend ce qui pourrait rendre plus facile pour vous de comprendre:

Le secteur informel de l'intuition est qu'une méthode est plus précise qu'une autre si l'une invocation gérées par la première méthode peut être transmise à l'autre sans une erreur de compilation.

Donc, si vous avez:

void foo(String x)
void foo(Object x)

chaque invocation traitées par foo(String) pourrait être prise en charge par foo(Object), mais l'inverse n'est pas le cas. (Par exemple, vous pourriez l'appeler foo(new Object()) et qui n'a pas pu être traitées par foo(String).)

9voto

TAsk Points 7431

Suite à la déclaration de la JSL§15.12.2.5 des réponses qui,

Le secteur informel de l'intuition est qu'une méthode est plus spécifiqueque une autre si l'une invocation gérées par la première méthode pourrait être passée sur l'autre sans une erreur de compilation.

Cas 1

  • Vous pouvez passer n'importe quoi dans un constructeur qui prend en Object tout en nous ne peut pas passer à d'autre chose que d' Map dans le premier constructeur. Donc, tout ce que je passe en Map constructeur peut être géré par l' Object constructeur et c'est pourquoi, Test(Map map) devient le grain spécifique.

Cas 2

  • Depuis B s'étend Aici Test(B b) constructeur devient de plus en plus spécifiques. Comme nous pouvons le transmettre B en Test(A a) grâce à l'héritage.

Cas 3

  • Dans ce cas, il n'y a pas de conversion directe de représenter le plus spécifique de la méthode et des résultats dans l'ambiguïté.

6voto

Jordi Points 296

Ce comportement est dû au fait que E n'est pas plus spécifique que A, car ils appartiennent à différentes hiérarchies, ils ne peuvent pas être comparés. Ainsi, lorsque vous transmettez une valeur NULL, Java ne peut pas savoir quelle hiérarchie utiliser.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X