Desserialização de objeto ArrayList

13 respostas
r_Jovelli

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:

13 Respostas

pmlm

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.

moacirjava

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

r_Jovelli

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:

lina

Oi,

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

Tchauzin!

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…

:?: :?: :?:

edmarr

[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…

:?: :?: :?:

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

gomesrod

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.

r_Jovelli

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:

edmarr

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 .

gomesrod

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”).

r_Jovelli

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:

moacirjava

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

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();
        }        
    }
}
r_Jovelli

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...

8) 8) 8)

Este é o código que desenvolvi para serializar:

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();
			}
		}
	}

E este para desserializar:

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();
		}
	}
Criado 7 de setembro de 2009
Ultima resposta 13 de set. de 2009
Respostas 13
Participantes 6