Desserialização de objeto ArrayList

Boa noite pessoal, estou tentando fazer uma serialização e posterior desserialização de um objeto tipo ArrayList…

Ao serializar não acontecem erros nem nada, mas quando tento desserializar aparece o warning abaixo, eu queria entender o porque disso, não quero desenvolver de qlq jeito, eu prezo pela qualidade… desde já agradeço… segue o método abaixo que invoca a mensagem:

		public void actionPerformed(ActionEvent e) {
			ArrayList<Short> recebeEstado;

			try {
				FileInputStream fis = new FileInputStream(new File("/estadoObj.ser"));
				ObjectInputStream in = new ObjectInputStream(fis);

				recebeEstado = (ArrayList<Short>) in.readObject();
			} catch(Exception ex) {
				ex.printStackTrace();
			}
		}

quando compilo a classe com esse método aparece a seguinte mensagem:

Note: BeatBox.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

Aguardo… :slight_smile: :slight_smile: :slight_smile:

Estás a dizer que o objecto a ser lido é um ArrayList de Short mas o compilador não tem maneira de validar se isso é verdade ou não.

Só uma perguntinha, por quê vc quer serializar um ArrayList?

Ora, porque eu quero, há algum motivo para eu não querer? consome mais memória ou coisa do tipo???
E tb da maneira como estou fazendo aqui eu não sei a quantidade exata de números do tipo short que serão armazenados na ArrayList, se soubesse utilizaria um array… sem problemas…
:wink:

Sim, exatamente. Todo objeto armazenado na ArrayList é armazenado como Object ou seja o compilador não sabe o que necessariamente foi armazenado, mas ao verificar que está sendo convertido para o tipo correto, ele não reclama… mas dessa vez ele me deu esse warning…

Aguardo respostas
:slight_smile: :slight_smile: :slight_smile:

Oi,

A resposta já foi dita. Qual outra resposta você quer?

Tchauzin!

Olá pessoal, então Lina o que o pmlm me respondeu é o que acontece com qualquer objeto adicionado em um ArrayList, o objeto perde o tipo e é retornado como Object e o compilador não tem como saber o que este Object é exatamente, mas ao ver que está sendo convertido para um tipo igual ao da variável que recebe ele não chia, mas dessa vez apareceu essa nota:

Eu só queria ver se alguém saberia me dizer por que o compilador está dizendo que esta é uma operação não checada ou insegura…

:?: :?: :?:

[quote=[r.Jovelli]]Olá pessoal, então Lina o que o pmlm me respondeu é o que acontece com qualquer objeto adicionado em um ArrayList, o objeto perde o tipo e é retornado como Object e o compilador não tem como saber o que este Object é exatamente, mas ao ver que está sendo convertido para um tipo igual ao da variável que recebe ele não chia, mas dessa vez apareceu essa nota:

Eu só queria ver se alguém saberia me dizer por que o compilador está dizendo que esta é uma operação não checada ou insegura…

:?: :?: :?: [/quote]

Eh um warning que ele te informa que esta passando uma parte do codigo vc trabalhou com genericos e a outra parte nao ultilizou para melhor exemplificar basta vc compilar a classe com ,

 javac -Xlint:uncheched nomedaclasse.java 

Ira lhe falar qual parte do seu código esta insegura

Imagine que em algum lugar da aplicação você serializou um ArrayList, e depois faz isso:

ObjectInputStream in = /* blablabla */ List<Short> myShorts = (ArrayList<Short>) in.readObject();
Quando esse trecho for executado você não terá nenhum erro, pois como sabemos os generics não existem após a compilação (um ArrayList foi serializado, um ArrayList é o que vai ter!). Pois bem, a lista myShorts vai passear entre os objetos sem nenhum problema - até o momento em que você tentar utilizar algum elemento:

short firstValue = myShorts.get(0).shortValue();

Imagine a confusão, estamos chamando um método de Short em um objeto que é String. Um erro tão medonho que nem imagino qual exceção será lançada :shock: . E você lá tentando debugar e descobrir por que diabos a sua List está populada com Strings.

O que isso significa? NADA! HAHAHAAH
Mas espero que ajude a entender por que esta operação é INSEGURA.

Blz pessoal a explicação do gomesrod me deu uma boa idéia de o porque esta serialização ser considerada arriscada, ainda compilando com javac -Xlint:unchecked nomeClasse aparece que é requerido ArrayList e que foi encontrado Object…

Bom, ficou claro a questão…

Vlw pelo apoio…

Um abraço… :slight_smile: :slight_smile: :slight_smile:

Não e a serialização que eh arriscada , foi simplesmente pq vc esta usando métodos genéricos em um local eh em outro nao , somente isto o warning , te mostrando que pode ter falhas e talz .

Do Mais Bom Estudo .

O diabinho está certo. Veja esse caso: você serializou uma String em algum lugar do programa, e depois fez isso:

ObjectInputStream in = /* blablabla */ Short shortJeans = (Short) in.readObject();
Não vai dar erro de compilação, nem warning, e na hora de executar tomamos na cara uma big exceção. Mas de certa forma isso é bom, pois sabemos exatamente o ponto onde está o erro e como rastreá-lo.
Diferente do outro exemplo, em que você esperava um ArrayList e o que estava serializado também era um ArrayList. A atribuição vai acontecer sem problemas e o erro aparece em um outro lugar qualquer da aplicação! Ou seja, a encrenca não foi tanto por causa da desserialização e sim por passar de um “mundo não-generic” para um “generic”. É uma situação muito mais traiçoeira, e por isso o compilador dá aquele warning.

Lembre-se do antigo provérbio chinês: O COMPILADOR É SEU AMIGO.

E para finalizar, uma informação. Não sei se você já sabe disso, mas vou colocar mesmo assim: o compilador avisou que essa atribuição é insegura, mas se você tem realmente certeza que está tudo Ok existe um jeito de dizer a ele “Obrigado pelo aviso, não precisa mais avisar porque já conferi tudo direitinho” - Coloque sobre o método a anotação @SuppressWarnings(“unchecked”).

Eae pessoal eu li estes comentários e ainda dei uma pesquisada na net e li mais sobre os generics e agora deu pra entender porque do warnning e como funciona melhor os
generics, o artigo abaixo me ajudou a entender melhor e talz…

http://www.plugmasters.com.br/sys/materias/864/1/Tipos-gen�ricos-em-Java-(Generics)

Então eu não conhecia esse comando não, é novo pra mim, mas preferi não usá-lo, é bom ter um warnning para avisar, não sei se vou alterar esse código qualquer dia…
Mas vlw mesmo a todos pela força…

Se alguém precisar e eu puder contribuir… estamos ae…

Um abraço… :smiley: :smiley: :smiley:

[quote=[r.Jovelli]Boa noite pessoal, estou tentando fazer uma serialização e posterior desserialização de um objeto tipo ArrayList…

[/quote]

Quando vc disse que queria “serializar um ArrayList” te confesso que não entendi bem o título da sua dúvida mas acho que o que vc quer é isso aqui…

public class Testes {
    static class Teste implements Serializable{
      List<String> dado = new ArrayList<String>();  
      public Teste(){}
		
      protected void addDado(String d){
        dado.add(d);
      }	
      protected List<String> getDado(){
        return dado;
      }
    }

    public static void main(String[] args){
      Teste t = new Teste();
      try{
          File arquivo = new File("C:\arquivo");
          arquivo.mkdir();
          File arqui = new File(arquivo, "arqui.mrc");
          FileOutputStream f = new FileOutputStream(arqui);
          ObjectOutputStream o = new ObjectOutputStream(f);
  	  int i = 0;
	  while(i < 10){
	    t.addDado("a");
	    i++;
          }
          o.writeObject(t);
          FileInputStream fi = new FileInputStream(arqui);
          ObjectInputStream oi = new ObjectInputStream(fi);
          t = (Teste) oi.readObject();
          List<String> lista = t.getDado();
          System.out.println(lista);
        }
        catch(FileNotFoundException f){
            f.printStackTrace();
        }
        catch(IOException i){
            i.printStackTrace();
        }
        catch(ClassNotFoundException c){
            c.printStackTrace();
        }        
    }
}

Na mosca cara, é exatamente isso que eu quero fazer, a única diferença é que no seu exemplo vc sabe que serão armazenados dez números e no código que eu fiz aqui eu não sei quantos números serão armazenados na ArrayList… se eu soubesse quantos números exatamente seriam armazenados eu serializaria um array de Short…
Mas é isso mesmo moacirjava, consegui entender o warnning e tudo, vlw pela força…

Um abraço…

Este é o código que desenvolvi para serializar:

[code]private class MySerializarListener implements ActionListener {
	public void actionPerformed(ActionEvent e) {
		ArrayList<Short> estadoCheckBox = new ArrayList<Short>();

		for (short i = 0; i < 256; i++) {
			if (checkBoxList.get(i).isSelected()) {
				estadoCheckBox.add(i);
			}
		}

		try {
			FileOutputStream fos = new FileOutputStream(escolherArquivo("salvar")); //abre um JFileChooser com o método showSaveDialog();
			ObjectOutputStream out = new ObjectOutputStream(fos);
			out.writeObject(estadoCheckBox);
		} catch(Exception ex) {
			ex.printStackTrace();
		}
	}
}[/code]

E este para desserializar:

[code]
private class MyDesserializarListener implements ActionListener {

	@SuppressWarnings("unchecked") //Faz com que o método ao ser compilado não mostre warnings referentes a unckecked
	public void actionPerformed(ActionEvent e) {
		ArrayList<Short> recebeEstado;

		for (short i = 0; i < 256; i++) {
			checkBoxList.get(i).setSelected(false);;
		}

		try {
			FileInputStream fis = new FileInputStream(escolherArquivo("abrir"));
			ObjectInputStream in = new ObjectInputStream(fis);

			recebeEstado = (ArrayList<Short>) in.readObject();
			for (Short percObj : recebeEstado) {
				checkBoxList.get(percObj).setSelected(true);
			}

		} catch(Exception ex) {
			ex.printStackTrace();
		}

		UtilMidi.sequencer.stop();
		criarTrilhaIniciar();
	}
}[/code]