Me deparei com esta questão em um teste,
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);
}
}
A saída deste programa é "String Version". Mas não consegui entender por que passar um nulo para um método sobrecarregado escolheu a versão de string. É null uma variável String apontando para nada?
No entanto, quando o código é alterado para,
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);
}
}
ele dá um erro de compilação dizendo "O método do método (StringBuffer) é ambíguo para o tipo MoneyCalc"
java
overloading
zakSyed
fonte
fonte
Respostas:
Uma referência nula pode ser convertida em uma expressão de qualquer tipo de classe. Então, no caso de
String
, isso é bom:A
String
sobrecarga aqui é escolhida porque o compilador Java escolhe a sobrecarga mais específica , conforme a seção 15.12.2.5 do JLS . Em particular:Em seu segundo caso, os dois métodos ainda são aplicáveis, mas nenhum
String
nemStringBuffer
é mais específico do que o outro, portanto, nenhum método é mais específico do que o outro, daí o erro do compilador.fonte
Object
pode pegar qualquer tipo e envolvê-lo em umObject
, enquanto umString
só pode pegar umString
. Nesse caso,String
é mais específico de um tipo em comparação com oObject
tipo.question.method((String)null)
)Além disso, o JLS 3.10.7 também declara que "nulo" é um valor literal do "tipo nulo". Portanto, existe um tipo chamado "nulo".
Posteriormente, o JLS 4.1 afirma que existe um tipo nulo do qual é impossível declarar variáveis, mas você pode usá-lo apenas por meio do literal nulo. Mais tarde, diz:
Por que o compilador opta por ampliá-lo para String pode muito bem ser explicado na resposta de Jon .
fonte
Você pode atribuir a
string
a umnull
valor para que seja válido e o pedido para java e a maioria das linguagens de programação seja adequado para o tipo mais próximo e depois para o objeto.fonte
Para responder à pergunta no título:
null
não é nem aString
nem anObject
, mas uma referência a qualquer um pode ser atribuídanull
.Na verdade, estou surpreso que esse código até compile. Tentei algo semelhante anteriormente e recebi um erro do compilador dizendo que a chamada era ambígua.
No entanto, neste caso, parece que o compilador está escolhendo o método mais baixo na cadeia alimentar. Presume-se que você queira a versão menos genérica do método para ajudá-lo.
Terei que ver se consigo descobrir o exemplo em que obtive um erro do compilador neste (aparentemente) mesmo cenário ...]
EDIT: entendo. Na versão que fiz, eu tinha dois métodos sobrecarregados aceitando um
String
e umInteger
. Nesse cenário, não há parâmetro "mais específico" (como emObject
eString
), portanto, ele não pode escolher entre eles, ao contrário do seu código.Pergunta muito legal!
fonte
Como o tipo String é mais específico do que o tipo Object. Digamos que você adicione mais um método de tipo Integer.
Então, você obterá um erro do compilador dizendo que a chamada é ambígua. Como agora, temos dois métodos igualmente específicos com a mesma precedência.
fonte
O compilador Java fornece a maioria dos tipos de classe derivados para atribuir nulos.
Aqui está o exemplo para entender:
saída: Classe B.
por outro lado:
Resultado: o método fun (C) é ambíguo para o tipo MyTest
Espero que ajude a entender melhor este caso.
fonte
Fonte: https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.2.5
Conceito: Método mais específico
Explicação: Se mais de um método de membro estiver acessível e aplicável a uma chamada de método, é necessário escolher um para fornecer o descritor para o despacho do método em tempo de execução. A linguagem de programação Java usa a regra de que o método mais específico é escolhido. Tente lançar o nulo em um tipo específico e o método que você deseja será chamado automaticamente.
fonte
Eu diria que não. NULL é um estado, não um valor. Confira este link para obter mais informações sobre isso (o artigo se aplica ao SQL, mas acho que ajuda na sua pergunta também).
fonte
null
é definitivamente um valor, conforme definido no JLS.