Tenho algumas dúvidas sobre certas partes da correspondência definitiva na especificação da linguagem Java.
Por exemplo, em 6.3.1.1:
Operador condicional-and && As seguintes regras se aplicam a uma expressão condicional-and
a && b
(§15.23):• Uma variável de padrão introduzida por
a
quando true é definitivamente correspondida emb
.• Uma variável de padrão é introduzida por
a && b
quando verdadeiro se (i) for introduzida pora
quando verdadeiro ou (ii) for introduzida porb
quando verdadeiro.Deve-se notar que não há regra para introduzir uma variável de padrão por
a && b
quando false. Isso ocorre porque não é possível determinar em tempo de compilação qual operando será avaliado como false .
Não entendo por que o motivo para "não há regra para introduzir uma variável de padrão por a && b quando falso" é "não é possível determinar em tempo de compilação qual operando será avaliado como falso".
Se houver
a instanceof String s
então a variável padrão s
é introduzida por esta expressão somente quando o valor desta expressão é true . Então podemos dizer "a variável padrão s
é introduzida pela expressão a instanceof String s
quando true".
Seja " quando verdadeiro " ou " quando falso ", ambos parecem ser apenas escritos gerados pela previsão do valor de uma expressão. (Ou melhor, eles levam o valor da expressão em consideração.)
Acho que isso é completamente diferente de " quando verdadeiro " ou " quando falso " que aparecem na atribuição definida .
Por exemplo:
{
int k;
int n = 5;
if (n > 2)
k = 3;
System.out.println(k); /* k is not "definitely assigned"
before this statement */
}
As seguintes regras se aplicam a uma declaração
if (e) S
:•
V
é [des]atribuído apósif (e) S
se e somente se V é [des]atribuído apósS
eV
é [des]atribuído apóse
quando falso .
Acho que se " quando falso " aqui for o mesmo que em correspondência definida , então k
será definitivamente atribuído aqui.
Então, acho que a atribuição definida não leva em conta o valor de uma expressão ( exceto para algumas expressões com constantes de tempo de compilação ), (assim como a especificação declara), (assim como neste exemplo), mas a correspondência definida obviamente considera o valor da expressão (assim como no exemplo anterior).
Nesse caso, acho que devo conseguir adicionar o seguinte depois da versão 6.3.1.1:
Uma variável de padrão é introduzida por a && b
quando falso se (i) for introduzida por a
quando falso ou (ii) for introduzida por a
quando verdadeiro ou (iii) for introduzida por b
quando a
verdadeiro.
Acho que não há nada de errado nisso, porque estou apenas considerando os valores dessas expressões e anotando as situações previstas. Isso não tem nada a ver com os valores em tempo de compilação.
No entanto, a nota de rodapé é completamente diferente da minha visão e contém motivos que não entendo de forma alguma.
Então estou aqui para pedir ajuda. Obrigado por ler e responder.
Se uma variável de padrão é introduzida é muito diferente de atribuição definida. A parte que você citou de 16.2.7 é sobre instruções if, não sobre
&&
.Intuitivamente, não há regra para "uma variável de padrão é introduzida por
a && b
quando false" porque não podemos saber em tempo de compilação qual padrão é correspondido. Considere:Qual variável de padrão deve ser definitivamente correspondida no
else
branch? Nenhuma variável de padrão deve ser introduzida aqui, porque ifelse
é executado, isso significa queo
não é uma string e um inteiro. Pode ser uma string, pode ser um inteiro, pode ser qualquer outra coisa. Não obtivemos nenhuma informação útil sobreo
in theelse
branch.Vamos dar uma olhada na seção 6.3.2.2 da especificação. Variáveis de padrão introduzidas por
o instanceof String s && o instanceof Integer i
when false serão definitivamente atribuídas noelse
branch. E de acordo com sua adição proposta à especificação,s
é uma variável de padrão introduzida poro instanceof String s && o instanceof Integer i
when false, porques
é uma variável de padrão introduzida poro instanceof String s
when true, então a condição (ii) se aplica. Isso é obviamente incorreto porque oelse
ainda pode ser executado ifo
não é umString
.O mesmo se aplica a qualquer outro par de padrões de tipos que você queira combinar.
Na verdade, a condição (iii) em sua proposta também não está bem definida. "introduzido por b quando a é verdadeiro" não está definido. Existem apenas 3 formas conforme listadas na parte logo antes do cabeçalho da seção de 6.3.1 :
Você poderia dizer algo assim:
que reflete esta regra para
&&
atribuição definitiva ( 16.1.2 ):No entanto, isso é discutível, porque a mesma variável de padrão não pode ser introduzida por duas expressões diferentes. Mas se pudesse, seria um caso como este:
A variável pattern foi introduzida no Java 16.
por exemplo:
a linha " não há regra para introduzir uma variável de padrão por a && b quando falso "
considere o exemplo abaixo:
isso causará um conflito em tempo de compilação, porque