"Frederico Charle S. Faria" wrote:
>
> Einar Saukas wrote:
>
> > "Frederico Charle S. Faria" wrote:
> > >
> > > Agora o motivo porque os projetores de Java decidiram por isso - exigir o
> > > super() na primeira linha impossibilitando mesmo a utilização de variáveis
> > > não membros - com certeza foi devido a fatores de complexidade de
> > > implementação e performanca. ( da MV)
> >
> > Muito obrigado pelas informações, mas eu conheço um pouco sobre
> > técnicas de compilação e não vejo porque a utilização de variáveis
> > locais afetaria significativamente a implementação e muito menos a
> > performance. Afinal de contas, para um compilador, esse trecho de código:
>
> Primeiramente voce entendeu errado! A perda de performance e a dificuldade de
> implementação
> não se referem a utilização de variáveis locais , mas sim a decisão de projeto
> dos fundadores do Java
> ,ou seja, exigir que o super() seja o primeiro comando do construtor.
Na verdade eu não entendi errado, é que eu me expressei mal. Eu
deveria ter sido mais claro. O que eu quis dizer é que eu não vejo porque
a utilização de variáveis locais ANTES DA CONSTRUÇÃO DA CLASSE BASE (AO
INVÉS DE SÓ DEPOIS) afetaria significativamente a implementação e muito
menos a performance.
> Espero que perceba a diferença, e veja que se fosse de maneira contrária a
> implementação seria mais difícil e a
> performance com certeza mais pobre!!!
Em relação ao compilador, eu concordo que a implementação seria
um pouco mais difícil, porque no parser ele teria que sempre verificar
se o super() não aparece mais "pra frente", depois da inicialização de
algumas variáveis locais. Mas isso não é tão complicado assim, a
diferença no tempo de compilação dificilmente seria perceptível, quer
dizer, realmente afetaria um pouco a implementação mas não de forma
significativa.
Já a performance depende apenas do tempo de interpretação do
bytecode, algo que não é afetado pela complexidade do parser.
> > MessageOutputStream() throws java.io.IOException {
> > ByteArrayOutputStream tmp = new ByteArrayOutputStream();
> > super(tmp); // ERRO!
> > }
> >
> > Tem praticamente a mesma complexidade deste aqui:
> >
> > MessageOutputStream() throws java.io.IOException {
> > super(new ByteArrayOutputStream());
> > }
>
> Voce está errado! Isto depende da implementação do Compilador.. Para C++ , por
> exemplo, existem
> várias implementações diferentes para isso! Vejo o livro do Meyers, ele cita
> exemplos de implementação
> deste tipo. Tem compiladores que usam algumas técnicas de otimização quando é
> utilizada esta última construção.
> Talvez alguns compiladores Java utilizem esta mesma técnica.
Mas em relação a otimizações no código gerado, se houver operações
envolvendo temporários dentro do construtor, não vai fazer realmente muita
diferença se elas ocorrem antes ou depois da chamada ao construtor da
classe base.
> > À primeira vista, o compilador só tem que ser um pouco mais
> > cuidadoso na manipulação da pilha de execução, mas isso parece ser
> > muito fácil de resolver. Será que tem algum outro fator que eu não
> > percebi?
>
> É fácil de perceber que é mais ineficiente... Imagine um construtor com várias
> chamadas de métodos
> aninhados, com a implementação corrente basta para o compilador analisar a
> primeira linha do construtor.
> Se não fosse assim o compilador teria que analisar toda a a´rvore de métodos
> aninhados para
> garantir que não houvesse nenhuma referencia a algum atributo da classe antes da
> chamada do super.
> Mais memória e mais processador!!. Este é um simples exemplo...
É verdade, você tem razão! A questão não é performance, mas sim
a velocidade de compilação. Os idealizadores do Java deveriam estar
preocupados em manter uma sintaxe que permitisse uma compilação o mais
direta possível, para que as ferramentas de desenvolvimento não ficassem
muito pesadas. Este provavelmente também foi um dos fatores que os
levaram a deixar de fora recursos como sobrecarga de operadores, uma das
coisas que tornam a compilação de C++ algo tão pesado. OK, muito obrigado
pelas informações!
Essa discussão está bem legal, mas de qualquer forma o problema
original continua em aberto: como fazer para instanciar uma classe,
repassá-la para o construtor da classe base e depois ainda guardá-la
numa variável de instância?
Ou, colocando o problema de outra forma, existe alguma maneira
de implementar algo assim:
class MessageOutputStream extends ObjectOutputStream {
private ByteArrayOutputStream _bos;
MessageOutputStream() throws java.io.IOException {
super(_bos = new ByteArrayOutputStream()); // ERRO!
}
}
... de forma que o cliente possa usar essa classe fazendo
apenas isto:
MessageOutputStream var = new MessageOutputStream();
Alguém tem mais sugestões?
Um abraço,
Einar Saukas
Technical Consultant
Summa Technologies, Inc.
http://www.summa-tech.com
--------------------------- LISTA SOUJAVA ---------------------------
http://www.soujava.org.br - Sociedade de Usuários Java da Sucesu-SP
[para sair da lista: http://www.soujava.org.br/forum/cadastrados.htm]
---------------------------------------------------------------------