Oi Einar,
ainda não sei se compreendi bem o seu problema. Mas vamos lá!
Quando você está implementando um método construtor e faz a chamada ao
construtor da superclasse, utilizando super(), esta chamada deve ser feita
antes de qualquer ação dentro do construtor. Isto é uma característica não só
do Java, mas de outras linguagens de programação OO. Por isso sua primeira
tentativa não funcionou:
class MessageOutputStream extends ObjectOutputStream {
private ByteArrayOutputStream _bos;
MessageOutputStream() throws java.io.IOException {
super(_bos = new ByteArrayOutputStream()); // ERRO!
}
}
Neste caso, ele tenta primeiro fazer _bos = new ByteArrayOutputStrem() antes
de chamar o super( _bos);
Você poderia fazer:
import java.io.*;
class MessageOutputStream extends ObjectOutputStream {
private ByteArrayOutputStream _bos = new ByteArrayOutputStream();
MessageOutputStream() throws java.io.IOException {
super();
}
MessageOutputStream(ByteArrayOutputStream bos) throws java.io.IOException {
super(bos);
_bos = bos;
}
}
No caso acima não enviando o parâmetro para o superconstrutor, já que durante
a execução ele faria a instanciação do new ByteArrayOutputStream() antes de
invocar o super. Ou seja, seu problema está resolvido, porque não tem solução.
O cliente vai ter que enviar a referência do objeto se você quiser usar o
super, ou então não usa o super e boa.
Questoes conceituais, talvez você já saiba de tudo que está abaixo, mas pode
ser interessante para o pessoal que está começando:
Os dados criados dentro de uma classe são pertencentes a esta classe, mas
podem ser referenciados por outros objetos enquanto a classe ainda não tenha
sido destruída. Isto é uma característica do encapsulamento. Quando declaramos
um objeto e passamos como referência um outro, estamos apenas apontando para o
objeto real, e portanto não temos uma nova cópia do objeto referenciado. Isto
significa que se o objeto original for destruído a referencia ficará,
obviamente sem referência. Mas acho que você já sabia disso... estou me
prolongando e vou acabar complicando... :)
Escrevi um programa bem rapidamente para testar o que estava falando, está
abaixo:
import java.io.*;
class MessageOutputStream extends ObjectOutputStream {
private ByteArrayOutputStream _bos = new ByteArrayOutputStream();
MessageOutputStream() throws java.io.IOException {
super();
}
MessageOutputStream(ByteArrayOutputStream bos) throws java.io.IOException {
super(bos);
_bos = bos;
}
MessageOutputStream(FileOutputStream fos) throws java.io.IOException {
super(fos);
}
ByteArrayOutputStream getBos()
{
return _bos;
}
public static void main (String a[])
{
try{
FileOutputStream ostream = new FileOutputStream("t.tmp");
MessageOutputStream m = new MessageOutputStream(ostream);
m.writeObject("\n Dado adicionado em m");
System.out.println("1:"+m.toString());
m.flush();
// MessageOutputStream b = m;
m = null;
MessageOutputStream b = m;
Runtime.getRuntime().gc();
b.writeObject("\nDado adicionado em b!!!!");
System.out.println("2:"+b.toString());
ostream.close();
}
catch (IOException e) {
System.out.println("erro");
}
}
}
Tente inverter os comentário e o erro que surgirá na execução:
Exception in thread "main" java.lang.NullPointerException
at MessageOutputStream.main(MessageOutputStream.java:35)
Por causa da perda da referência.
É isso, se não ajudei, desculpe.
[]'s
Handerson Ferreira Gomes
Einar Saukas wrote:
> Ricardo Muneo Kayo wrote:
> >
> > Vc jah tentou usar essa classe com a sua ultima implementacao(4a. do
> > email)? Funcionou???
>
> Sim, funcionou.
>
> > Pelo que eu entendi, vc quer fazer uma heranca multipla em JAVA, meio
> > mascarado, nao eh??? Acho que nao vai funcionar!!!
>
> Não, eu simplesmente queria fazer uma herança simples da classe
> ObjectOutputStream mesmo. A única dificuldade é que eu preciso preservar
> o parâmetro que eu estou passando para o construtor dessa classe.
>
> É bastante razoável que minha primeira opção não funcione, porque
> eu não posso mesmo acessar variáveis da instância antes de inicializar a
> base. Mas quanto à segunda opção (usar variáveis temporárias antes de
> inicializar a base), eu não vejo nenhum motivo para isso não funcionar,
> porque afinal de contas tais informações ficam armazenadas na pilha e
> não na área de memória da instância.
>
> Tem alguém nessa lista de discussão que acompanhe mais de perto
> o processo de padronização do Java (Bruno?) e saiba dizer se tem algum
> motivo para essa restrição? Será que isso é imposto pelo padrão ou
> simplesmente uma particularidade da implementação atual do JDK?
>
> Um abraço,
>
> Einar Saukas
> Technical Consultant
> Summa Technologies, Inc.
> http://www.summa-tech.com
>
> > Einar Saukas wrote:
> > >
> > > Oi pessoal!
> > >
> > > Encontrei um problema interessante no projeto em que estou
> > > trabalhando, será que alguém tem alguma sugestão? Minha intenção
> > > era fazer uma classe assim, só que não funciona:
> > >
> > > class MessageOutputStream extends ObjectOutputStream {
> > > private ByteArrayOutputStream _bos;
> > > MessageOutputStream() throws java.io.IOException {
> > > super(_bos = new ByteArrayOutputStream()); // ERRO!
> > > }
> > > }
> > >
> > > Todas as outras soluções semelhantes que eu consegui imaginar
> > > também não funcionam, como essa por exemplo:
> > >
> > > class MessageOutputStream extends ObjectOutputStream {
> > > private ByteArrayOutputStream _bos;
> > > MessageOutputStream() throws java.io.IOException {
> > > ByteArrayOutputStream tmp = new ByteArrayOutputStream();
> > > super(tmp); // ERRO!
> > > _bos = tmp;
> > > }
> > > }
> > >
> > > Na verdade, existe uma única variante que funciona, mas é
> > > uma péssima solução:
> > >
> > > class MessageOutputStream extends ObjectOutputStream {
> > > static ByteArrayOutputStream tmp;
> > > private ByteArrayOutputStream _bos;
> > > MessageOutputStream() throws java.io.IOException {
> > > super(tmp = new ByteArrayOutputStream());
> > > _bos = tmp;
> > > }
> > > }
> > >
> > > Por isso, a solução que eu acabei adotando foi deixar parte
> > > da inicialização para ser feita pelo "cliente" da classe:
> > >
> > > class MessageOutputStream extends ObjectOutputStream {
> > > private ByteArrayOutputStream _bos;
> > > MessageOutputStream(ByteArrayOutputStream bos)
> > > throws java.io.IOException {
> > > super(bos);
> > > _bos = bos;
> > > }
> > > }
> > >
> > > Em todo caso, se alguém tiver alguma idéia de como implementar
> > > minha intenção original, eu agradeço. Eu acho que não tem muito jeito,
> > > mas não custa nada perguntar...
> > >
> > > 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]
> ---------------------------------------------------------------------
--------------------------- 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]
---------------------------------------------------------------------