Neste artigo detalharemos as funcionalidades de uma das classes mais utilizadas e mais antigas do Java, a classe java.lang.System que está presente desde o jdk1.0.

Esta classe é mais conhecida pelos seus famosos métodos de entrada e saída de dados, como é o caso do tão famoso “System.out.println()”, recurso tão utilizado que o próprio Eclipse possui um atalho para sua criação, basta digitar: syso + CTRL ESPAÇO, automaticamente o Eclipse cria o comando “System.out.println()”. Mas a classe System não é apenas entrada e saída de dados, vai além disto, e nosso objetivo neste artigo é mostrar, com exemplos, o máximo de funcionalidades desta classe. Nas seções abaixo mostraremos cada funcionalidade com explicações e exemplos.

A Classe System

A classe System não pode ser estendida pois seus métodos são estáticos, sem a necessidade de criação de uma instância em memória. Além disso, esta classe tem 3 variáveis que são:

  • err: Sendo este do tipo PrintStream, armazena a saída padrão para mensagens de erro do sistema.
  • In: Sendo este do tipo InputStream, armazena a entrada padrão do sistema, que pode ser, por exemplo, um teclado ou um arquivo de texto (mostraremos mais a frente como funciona).
  • out: Sendo do mesmo tipo da variável “err” (PrintStream), esta variável armazena a saída padrão de mensagens da aplicação.

Esta classe possui diversos métodos, como já falamos anteriormente, e neste artigo mostraremos a maioria deles, explicando com exemplos e conceitos.

System.in

Sendo a variável “in”, uma variável que armazena a entrada padrão de dados da aplicação, conseguimos utilizar esta variável em diversas situações, vamos ver como funciona tal variável junto à classe Scanner, que nos auxilia no tratamento da entrada de dados do usuário. Observe a Listagem 1.

Listagem 1. Usando System.in junto com Scanner


  import java.util.Scanner;
   public class AppSystem {
              public static void main (String ... args){
               Scanner scan = new Scanner(System.in);
               System.out.println ("Digite: ");
               String entrada = scan.nextLine();
               System.out.println ("Você digitou: " +entrada);
         }
   }

O Scanner nos ajuda a tratar a entrada de dados do usuário, mas precisamos saber qual é essa entrada, pois pode ser pelo teclado, mas também pode ser via texto, então o System.in dita ao Scanner de qual entrada ele deve procurar o que o usuário digitou.

Se digitarmos na linha de comando:

 “java AppSystem”. 

O System.in padrão será o console, ou seja, a entrada deverá ser via teclado (digitação), porém se digitarmos no console:

“java AppSystem < entradaViaTexto.txt” 

Estamos direcionando a entrada para um arquivo de texto, neste caso o System.in estará atrelado a entrada via arquivo de texto, mais especificamente o “entradaViaTexto.txt”.

System.out

Diferente da variável “in”, que armazena a entrada de dados padrão, a variável “out” irá armazenar a saída de dados padrão, que geralmente é o próprio console, por padrão. Vamos ao exemplo da Listagem 2.

Listagem 2. Usando o System.out.print


  import java.math.BigDecimal;
    
  public class AppSystem {
         
         public static void main (String ... args){
               boolean b = false;
               
               System.out.print("booleano:" + b);
               
               int i = -1;        
               
               System.out.print("inteiro:" + i + "\n");
                        
               Double db = 10d;
               float ft = 20f;
               BigDecimal bgd = new BigDecimal(30);
               
               System.out.print("double: " + db + " float: "
                 + ft + " BigDecimal: " + bgd);
   
         }
   }

Perceba que optamos por usar o “\n” para dar um enter ao final na linha, mas poderíamos optar por usar diretamente o “System.out.println” que já faz o mesmo trabalho, colocando sempre um “\n” ao final de nossa string. Na Listagem 2 todas as saídas serão no console, como abaixo:

"booleano:falseinteiro:-1
  double: 10.0 float: 20.0 BigDecimal: 30” 

Mas poderíamos optar por mudar a saída padrão para um arquivo texto, assim como fizemos no “System.in”. Para fazer isso basta seguir a Listagem 3.

Listagem 3. Mudando a saída padrão do System.out


  import java.io.File;
  import java.io.FileNotFoundException;
  import java.io.FileOutputStream;
  import java.io.PrintStream;
  import java.math.BigDecimal;
    
  public class AppSystem {
         
         public static void main (String ... args) 
         throws FileNotFoundException{
               
               //Muda a saída padrão
               PrintStream out = new PrintStream(new FileOutputStream
                (new File("/tmp/teste.txt")));  
               System.setOut(out);  
               
               boolean b = false;
               //imprime o valor booelano
               System.out.print("booleano:" + b);
               
               int i = -1;        
               //imprime o valor do primitivo inteiro e dá um enter (\n") no final
               System.out.print("inteiro:" + i + "\n");
                        
               Double db = 10d;
               float ft = 20f;
               BigDecimal bgd = new BigDecimal(30);
               //imprime os valores Double(objeto), float(primitivo) e 
               //BigDecimal(objeto)
               System.out.print("double: " + db + " float: "
                + ft + " BigDecimal: " + bgd);
   
         }
   
  }

Perceba que logo no início do nosso método main criamos uma saída em “/tmp/teste.txt” e através do “System.setOut()” dizemos qual será a nova saída do nosso programa. Agora você terá tudo em um arquivo texto e nada no console.

System.err

Este segue a mesma estrutura do “System.out”, sendo que é utilizado para impressão de textos de erro, o próprio Eclipse muda a cor dos “System.err” que são impressos no console para vermelho, assim há uma diferenciação do “System.out”. Poderíamos até criar um Sistema de logging próprio usando o “System.err”.

Assim como nas outras variáveis: in e out. Você também pode alterar a saída padrão do err, para outra que não seja o console. Veja como na Listagem 4.

Listagem 4. Mudando a saída padrão do System.err


  import java.io.FileInputStream;
  import java.io.FileNotFoundException;
  import java.io.IOException;
  import java.io.InputStream;
   
  public class AppSystem {
   
    public static void main(String... args) 
     throws FileNotFoundException {
   
       try {
               InputStream input = 
                new FileInputStream("/tmp/dados.txt");
                 System.out.println("Aberto arquivo...");
             } catch (IOException e) {
                 System.err.println("Falha ao tentar abrir o arquivo:");
                  e.printStackTrace();
             }
   
    }
   
  }

System.arraycopy

O método arraycopy, como o próprio nome já sugere, disponibiliza a copia de todo um array para um outro, podendo ainda selecionar índices específicos que você deseja copiar, ou seja, caso você não queira copiar todo o array (apenas o meio dele), você poderá especificar explicitamente que partes você deseja copiar. Observe a Listagem 5.

Listagem 5. Copiando arrays com System.arraycopy


  import java.io.FileNotFoundException;
   
  public class AppSystem {
   
   public static void main(String... args) 
   throws FileNotFoundException {
   
    //Array de Origem
    char[] copyFrom = { 'd', 'e', 'c', 'a', 'f', 
     'f', 'e', 'i', 'n', 'a', 't', 'e', 'd' };
              
    //Array Destino
     char[] copyTo = new char[7];
              
    //2 - indice do começo da cópia do array de origem
    // para o array de destino, ou seja, vai copiar a partir 
    // desta posiçãocopyTo - array que irá receber a cópia
   //0 - análogo ao índice do começo da cópia do 
   // array de origem, só que aplicado ao array de destino.
   //7 - número de elementos copiados do array 
   //de origem. siz, lenght, tamanho...
               
   /*
    * 1º argumento (copyFrom): Array de origem
    * 2º argumento (valor 2): Posição de onde deverá começar a 
    * 3º argumento (copyTo): Array de Destino
    * 4º argumento (valor 0): Posição de onde deve começar a 
    * inserção dos elementos vindos do Array de Origem no Array de Destino
    * 5º argumento (valor 7): Tamanho do array de destino
    * */
    System.arraycopy(copyFrom, 2, copyTo, 0, 7);
     System.out.println(new String(copyTo));
   }
   
 }

O código da listagem acima está comentado, explicando o objetivo principal dele, que é a realização da cópia entre arrays.

System.getProperty(String chave) e System.getProperties()

Este método é muito útil para capturar valores de propriedades do sistema, tais como: nome do usuário logado, versão da jvm, sistema operacional e muitas outras propriedades, listaremos todas abaixo, mas antes veremos como usar tal método na Listagem 6.

Listagem 6. Usando o System.getProperty(String chave)


  import java.io.FileNotFoundException;
   
  public class AppSystem {
   
         public static void main(String... args) 
           throws FileNotFoundException {
   
               //Traz o nome do usuário logado no sistema
               System.out.println(System.getProperty ("user.name"));
         }
   
  }

O exemplo da listagem acima é simples e auto-explicativo. Você apenas precisa passar o nome da propriedade e o método “getProperty()” retorna para você o valor desta propriedade. Mas como saber quais as propriedades disponibilizadas pelo sistema ? Para isso vamos usar o método getProperties() que retorna uma lista de propriedades disponíveis, como na Listagem 7.

Listagem 7. Retornando lista de propriedades com System.getProperties()


  import java.io.FileNotFoundException;
   
  public class AppSystem {
   
         public static void main(String... args)
           throws FileNotFoundException {
   
               //Lista todas as propriedades disponíveis no sistema
               System.getProperties().list(System.out);
         }
   
  }

System.exit(int valor)

Este método termina a execução atual do programa, sendo o parâmetro valor quando possui valor igual a ZERO, significa que ocorreu um término normal do programa, e qualquer valor diferente de ZERO, significa término anormal do programa. Observe a Listagem 8.

Listagem 8. Usando System.exit(int valor)


  //termino de execução normal
  System.exit(0);
               
  //termino de execução Anormal
  System.exit(-1);

Com este artigo é possível perceber que o java.lang.System é muito mais do que uma simples classe para saída e entrada de dados, a mesma possuí outros recursos poderoso que podem ser utilizados diariamente em projetos simples ou complexos.