Minha pergunta está relacionada a System.in
e System.out
classes (pode haver outras como as da biblioteca Padrão). Por que é que? Isso não é uma prática ruim em POO? Não deve ser usado como: System.getIn()
e System.getOut()
? Eu sempre tive essa pergunta e espero encontrar uma boa resposta aqui.
java
object-oriented
encapsulation
Clawdidr
fonte
fonte
enum
para mantê-los ... emboraenum
fosse novo no Java 1.5 (não é uma opção nos 1,0 dias).final static
estatic final
? Se assim for, o que é?A verdadeira razão é que esse é um problema herdado. As
System.in,out,err
constantes faziam parte do Java 1.0 ... e provavelmente muito mais atrás. Quando ficou claro que o design apresentava problemas, era tarde demais para corrigi-lo. O melhor que eles puderam fazer foi adicionar osSystem.setIn,setOut,setErr
métodos no Java 1.1 e depois lidar com os problemas de especificação de linguagem 1 .Isso é semelhante à questão de por que existe um
System.arraycopy
método estático cujo nome viola as convenções de nomenclatura Java.Quanto a saber se isso é "design inadequado" ou não, acho que é. Há situações em que o manuseio atual sem OO é um problema sério. (Pense ... como você pode executar um programa Java dentro de outro quando seus requisitos de fluxo de "E / S padrão" entrarem em conflito. Pense ... código de teste de unidade que implica a alteração dos fluxos.)
No entanto, também posso me relacionar com o argumento de que a maneira atual de fazer as coisas é mais conveniente em muitos casos.
1 - É interessante notar que as
System.in,out,err
variáveis recebem menção especial no JLS como tendo "semântica especial". O JLS diz que se você alterar o valor de umfinal
campo, o comportamento é indefinido ... exceto no caso desses campos.fonte
Eu acredito que o objeto out é imutável, o que o torna de alguma forma seguro (isso é discutível) por ser mantido em um campo estático final público.
Muitas das classes no JDK não respeitam os melhores princípios de design orientado a objetos. Uma razão para isso é o fato de terem sido escritas há quase 20 anos, quando a Orientação a Objetos estava apenas emergindo como um paradigma convencional e muitos programadores simplesmente não estavam familiarizados com elas como estão agora. Um exemplo muito bom de mau design da API é a API Date & Time, que levou 19 anos para mudar ...
fonte
Essa resposta é ótima e verdadeira.
Eu queria acrescentar que, em alguns casos, foram feitos compromissos em prol da usabilidade.
Objetos do tipo String podem ser instanciados sem um evento new quando String não é um primitivo:
Sendo uma string não primitiva, deve ser instanciada assim:
Mas o compilador permite a opção mais curta e menos OO, porque String é de longe a classe mais usada na API.
Também as matrizes podem ser inicializadas de maneira não OO:
Estranho o suficiente, um objeto é uma instância de uma classe ou uma matriz . Matrizes de significado são um tipo de classe completamente separado.
As matrizes têm um
length
campo público que não é uma constante. Além disso, não há documentação nas matrizes de classe das quais é uma instância. (para não confundir com a classe Arrays ou java.reflect.Array).fonte
new String("Hello")
sempre criará um novo objeto String. EnquantoString s = "Hello";
usará o objeto internado. Compare:"Hello" == "Hello"
pode ser verdade, enquantonew String("Hello") == new String("Hello")
é sempre falso. Há uma mágica de otimização do tempo de compilação acontecendo no primeiro, o que não é possívelnew String("Hello")
. Veja en.wikipedia.org/wiki/String_interningString s = new String("Hello");
" que está incorreto. A opção mais curta (String s = "Hello";
) está mais correta devido à internação de strings.String
, não há opção "mais correta". Ambos estão corretos. Embora, como MichaelT diz, o mais curto seja o preferido por causa da internação por String.