Je suis tombé sur cette question dans un quiz,
public class MoneyCalc {
public void method(Object o) {
System.out.println("Object Verion");
}
public void method(String s) {
System.out.println("String Version");
}
public static void main(String args[]) {
MoneyCalc question = new MoneyCalc();
question.method(null);
}
}
La sortie de ce programme est "String Version". Mais je n'ai pas pu comprendre pourquoi passer un null à une méthode surchargée a choisi la version chaîne. Null est-il une variable String pointant vers rien?
Cependant, lorsque le code est changé en,
public class MoneyCalc {
public void method(StringBuffer sb) {
System.out.println("StringBuffer Verion");
}
public void method(String s) {
System.out.println("String Version");
}
public static void main(String args[]) {
MoneyCalc question = new MoneyCalc();
question.method(null);
}
}
il donne une erreur de compilation en disant "La méthode méthode (StringBuffer) est ambiguë pour le type MoneyCalc"
java
overloading
zakSyed
la source
la source
Réponses:
Une référence nulle peut être convertie en une expression de n'importe quel type de classe. Donc, dans le cas de
String
, c'est bien:La
String
surcharge ici est choisie parce que le compilateur Java sélectionne la surcharge la plus spécifique , conformément à la section 15.12.2.5 du JLS . En particulier:Dans votre deuxième cas, les deux méthodes sont toujours applicables, mais ni
String
niStringBuffer
n'est plus spécifique que l'autre, donc aucune méthode n'est plus spécifique que l'autre, d'où l'erreur du compilateur.la source
Object
peut prendre n'importe quel type et l'envelopper dans unObject
, alors qu'unString
ne peut prendre qu'unString
. Dans ce cas,String
est plus spécifique d'un type par rapport auObject
type.question.method((String)null)
)En outre, le JLS 3.10.7 déclare également que "null" est une valeur littérale du "type nul". Il existe donc un type appelé "nul".
Plus tard, le JLS 4.1 indique qu'il existe un type nul dont il est impossible de déclarer des variables, mais vous pouvez l'utiliser uniquement via le littéral nul. Plus tard, il dit:
Pourquoi le compilateur choisit de l'élargir à String pourrait bien être expliqué dans la réponse de Jon .
la source
Vous pouvez attribuer a
string
à unenull
valeur pour qu'elle soit valide et que l'ordre de java et de la plupart des langages de programmation corresponde au type le plus proche, puis à l'objet.la source
Pour répondre à la question du titre:
null
n'est ni unString
ni unObject
, mais une référence à l'un ou l'autre peut être attribuée ànull
.Je suis en fait surpris que ce code se compile même. J'ai essayé quelque chose de similaire précédemment et j'ai eu une erreur de compilation disant que l'appel était ambigu.
Cependant, dans ce cas, il semble que le compilateur choisisse la méthode la plus basse de la chaîne alimentaire. Cela suppose que vous souhaitiez la version la moins générique de la méthode pour vous aider.
Je vais devoir voir si je peux trouver l'exemple où j'ai eu une erreur de compilation dans ce scénario (apparemment) exactement le même, cependant ...]
EDIT: Je vois. Dans la version que j'ai créée, j'avais deux méthodes surchargées acceptant un
String
et unInteger
. Dans ce scénario, il n'y a pas de paramètre "le plus spécifique" (comme dansObject
etString
), il ne peut donc pas choisir entre eux, contrairement à votre code.Question très cool!
la source
Le type String est plus spécifique que le type Object. Disons que vous ajoutez une autre méthode qui prend un type Integer.
Ensuite, vous obtiendrez une erreur du compilateur indiquant que l'appel est ambigu. Comme maintenant, nous avons deux méthodes également spécifiques avec la même priorité.
la source
Le compilateur Java donne le type de classe le plus dérivé à affecter null.
Voici l'exemple pour le comprendre:
sortie: Classe B.
d'autre part:
Résultat : la méthode fun (C) est ambiguë pour le type MyTest
J'espère que cela aidera à mieux comprendre ce cas.
la source
Source: https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.2.5
Concept: méthode la plus spécifique
Explication: si plus d'une méthode membre est à la fois accessible et applicable à un appel de méthode, il est nécessaire d'en choisir un pour fournir le descripteur pour la distribution de méthode d'exécution. Le langage de programmation Java utilise la règle selon laquelle la méthode la plus spécifique est choisie. Essayez de convertir la valeur null sur un type spécifique et la méthode que vous souhaitez sera automatiquement appelée.
la source
Je ne dirais ni l'un ni l'autre. NULL est un état et non une valeur. Consultez ce lien pour plus d'informations à ce sujet (l'article s'applique à SQL, mais je pense que cela aide également à répondre à votre question).
la source
null
est très certainement une valeur, telle que définie dans le JLS.