[RESOLVIDO]Método antigo

7 respostas
lucas_guj

Pessoal ao compilar minha classe o terminado do linux diz o seguinte:

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

Vi em outro tópicos que isso é para informar que eu estou usando algum método antigo na API e já tem um novo. Se for isso mesmo como vou saber? Vou colocar o código aqui se alguém souber agradeço:

/**
 * ChatSimplesServer.java
 * Recebe e envia mensagens para os clientes
 * @author Lucas Santos
 * Criado em 08/05/2012, 23:13:39
 */
import java.io.*;
import java.net.*;
import java.util.*;

public class ChatSimplesServer {
    ArrayList clientOutputStreams; // Armazena os fluxos de saídas dos clientes conectados
    
    
    public static void main (String[] args) {
        new ChatSimplesServer().go();
    }
    
    /**
     * Cria um objeto ServerSocket em uma porta especifíca para aguarda solicitações de clientes.
     * Captura o fluxo de saída( mensagens recebidas ) de cada cliente e os adiciona ao ArrayList clientOutputStream( de fluxo de saídas de clientes ).
     * Cria um objeto Thread e executa a tarefa da classe interna ClientHandler( Manipulador de Clientes ).
     */
    public void go() {
        clientOutputStreams = new ArrayList();
        
        try {
            ServerSocket serverSock = new ServerSocket(5000); // cria um soquete de conexão na porta 5000
            
            // loop infinito
            while(true) {
                Socket clientSocket = serverSock.accept(); // aguarda solicitações de clientes e retorna um objeto Socker em uma porta diferente
                PrintWriter writerOutput = new PrintWriter( clientSocket.getOutputStream() ); // captura fluxo de saída( mensagens recebidas pelo servidor )
                clientOutputStreams.add(writerOutput); // adiciona o fluxo( objeto PrintWriter ao ArrayList de fluxo de saídas de clientes )
                Thread t1 = new Thread( new ClientHandler(clientSocket) );
                t1.setName("Manipulador de Clientes");
                t1.start();
                System.out.println("Conexão Estabelecida!");
            }
        }
        catch(Exception ex) {
            ex.printStackTrace();
        }
    } // fim do método go()
    
    /**
     * Classe interna Runnable( tarefa do thread "Manipulador de Clientes" ) que manipula os clientes.
     * Captura o fluxo de entrada e faz a leitura das mensagens no fluxo. Envia as mensagens ao método enviarATodos()
     */
    public class ClientHandler implements Runnable {
        BufferedReader reader;
        Socket sock;
        
        public ClientHandler(Socket clientSocket) {
            try {
                sock = clientSocket;
                InputStreamReader streamReader = new InputStreamReader( sock.getInputStream() ); // captura o fluxo de entrada
                reader = new BufferedReader(streamReader); // encadeia um objeto BufferedReader à um fluxo de entrada para uma melhor leitura
            }
            catch(Exception ex) {
                ex.printStackTrace();
            }
        } // fim do construtor
        
        public void run() {
            String messagem;
            
            try {
                // Enquanto houver mensagem a ser lida.
                while ( ( messagem = reader.readLine() ) != null) { 
                    System.out.println("Lido " + messagem);
                    enviarATodos(messagem);
                }
            }
            catch(Exception ex) {
                ex.printStackTrace();
            }
        } // fim do método run()
    } // fim da classe interna
    
    /**
     * Itera pela coleção de ArrayList de clientes. Escrevendo a mensagem no fluxo de saída de cada um deles.
     * @param messagem Mensagem a ser enviada para o fluxo de saída, para ser exibida para os clientes
     */
    public void enviarATodos( String messagem ) {
        Iterator it = clientOutputStreams.iterator();
        
        // Enquanto houver mais elementos na coleção
        while( it.hasNext() ) {
            try {
                PrintWriter writer = (PrintWriter) it.next(); // captura o fluxo de saída do objeto cliente atual
                writer.println(messagem);
                writer.flush();
            }
            catch(Exception ex) {
                ex.printStackTrace();
            }
        }
    } // fim do método enviarATodos()
}

7 Respostas

lucas_guj

Compilei em outro programa antes e ele disse que o erro estava enquanto estava escrevendo ClientHandler em:

public ClientHandler implements Runnable {
^

lucas_guj

Acredito que o erro seja aqui:

PrintWriter writerOutput = new PrintWriter( clientSocket.getOutputStream() );

Pois eu comento essa linha e ele compila sem informar o erro: uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details.

Não sei qual é o metodo novo em relação a getOutputStream()

E

O warning se deve a esta declaração:

ArrayList clientOutputStreams; // Armazena os fluxos de saídas dos clientes conectados

Isto tem duas coisas questionáveis.

  1. Isso é um ArrayList de o quê? É de PrintWriter? Se for, use: ArrayList clientOutputStreams;
  2. Use o estilo Javadoc para comentar uma declaração em vez de deixar o comentário à direita. Isso ajuda, por exemplo, em uma IDE, que conseguem ler os comentários JavaDoc e mostrar automaticamente o comentário quando você passa o mouse sobre o nome desse campo.
  3. (Opcional) Normalmente você usa List bla; bla = new ArrayList(); em vez de declarar a variável com o tipo da classe, se for possível, declare a variável com o tipo da interface que você vai usar e que é implementada pela classe que você estã pondo dentro da variável.

Ou seja:

/** Armazena os fluxos de saídas dos clientes conectados */
List<PrintWriter> clientOutputStreams;

e mais em baixo,

clientOutputStreams = new ArrayList<PrintWriter>();

Não se esqueça que é java.util.List, não java.awt.List (as IDEs normalmente escolhem java.awt.List em vez de java.util.List e acaba dando um monte de problemas depois :slight_smile: )

E

Uma outra vantagem é que isso acaba dispensando o cast na linha

PrintWriter writer = (PrintWriter) it.next();

que acaba ficando

PrintWriter writer = it.next();
lucas_guj

entanglement:
O warning se deve a esta declaração:

ArrayList clientOutputStreams; // Armazena os fluxos de saídas dos clientes conectados

Isto tem duas coisas questionáveis.

  1. Isso é um ArrayList de o quê? É de PrintWriter? Se for, use: ArrayList clientOutputStreams;
  2. Use o estilo Javadoc para comentar uma declaração em vez de deixar o comentário à direita. Isso ajuda, por exemplo, em uma IDE, que conseguem ler os comentários JavaDoc e mostrar automaticamente o comentário quando você passa o mouse sobre o nome desse campo.
  3. (Opcional) Normalmente você usa List bla; bla = new ArrayList(); em vez de declarar a variável com o tipo da classe, se for possível, declare a variável com o tipo da interface que você vai usar e que é implementada pela classe que você estã pondo dentro da variável.

Ou seja:

/** Armazena os fluxos de saídas dos clientes conectados */
List<PrintWriter> clientOutputStreams;

e mais em baixo,

clientOutputStreams = new ArrayList<PrintWriter>();

Não se esqueça que é java.util.List, não java.awt.List (as IDEs normalmente escolhem java.awt.List em vez de java.util.List e acaba dando um monte de problemas depois :slight_smile: )

Obrigado, você estava realmente certo quanto a declaração do ArrayList. Eu não estava colocando o tipo genérico.

Quanto a comentar usando o javadoc, eu uso apenas para métodos como está no meu código, você acha uma boa prática comentar com javadoc as variáveis também?

E em relação aos imports eu importei java.util.*; não usei awt não. Você só deu um aviso ou achou que eu tinha importado de awt?

E você disse assim:

Por que? Eu fiz isso e deu erro, disse que List é abstrato e não pode ser instanciada.

E você disse que eu posso dispensar o cast. Eu tentei e diz que dá tipos incompativeis porque retorna um Object e eu quero um PrintWriter para acessar os métodos de PrintWriter, pelo o que disse livro o java verifica o tipo da variavel de referencia na hora de chamar um metodo. Como eu tenho um variavel PrintWriter com referencia a Object e Object não tem o método flush(), da erro.

E
  1. Declare

List clientOutputStreams;

e na hora de criar o objeto, use

clientOutputStreams = new ArrayList();

É óbvio que não se pode dar “New” em uma classe abstrata ou em uma interface.

  1. De novo, só funciona direitinho você eliminar o cast se você declarar corretamente a variável it (desculpe, eu não tinha visto que a declaração também estava dando aviso de “tipo não genérico”). Eu deveria ter dito que era pra trocar para:
Iterator<PrintStream> it = clientOutputStreams.iterator();

Neste caso em particular, o código pode ser simplificado para:

for (PrintWriter writer: clientOutputStreams) {
            try {  
                writer.println(messagem);  
                writer.flush();  
            }  
            catch(Exception ex) {  
                ex.printStackTrace();  
            }  
        }

e você não tem de ficar lutando com um Iterator. Eu só uso um Iterator quando preciso de algo que precisa dele, como por exemplo remover algo da lista.

lucas_guj

entanglement:
1) Declare

List clientOutputStreams;

e na hora de criar o objeto, use

clientOutputStreams = new ArrayList();

É óbvio que não se pode dar “New” em uma classe abstrata ou em uma interface.

  1. De novo, só funciona direitinho você eliminar o cast se você declarar corretamente a variável it (desculpe, eu não tinha visto que a declaração também estava dando aviso de “tipo não genérico”). Eu deveria ter dito que era pra trocar para:
Iterator<PrintStream> it = clientOutputStreams.iterator();

Neste caso em particular, o código pode ser simplificado para:

for (PrintWriter writer: clientOutputStreams) {
            try {  
                writer.println(messagem);  
                writer.flush();  
            }  
            catch(Exception ex) {  
                ex.printStackTrace();  
            }  
        }

e você não tem de ficar lutando com um Iterator. Eu só uso um Iterator quando preciso de algo que precisa dele, como por exemplo remover algo da lista.

Agora sim. Achei até que ficou melhor o código retirando o Iterator e colocando o for aprimorado. Mas me diga uma coisa. Por que você optou por criar uma variável de referência do tipo List ao inves de ArrayList? Fora isso do resto eu entendi, obrigado.

Criado 10 de maio de 2012
Ultima resposta 11 de mai. de 2012
Respostas 7
Participantes 2