Esse processo de wrapping e unwrapping é entediante. O Java 5.0 em diante traz um recurso chamado de autoboxing, que faz isso sozinho para você, custando legibilidade:
Integer x = 5;
int y = x;
No Java 1.4 esse código é inválido. No Java 5.0 em diante ele compila perfeitamente. É importante ressaltar que isso não quer dizer que tipos primitivos e referências agora são a mesma coisa, isso é simplesmente um “açúcar sintático” (syntax sugar ) para facilitar a codificação.
Você pode fazer todos os tipos de operações matemáticas com os wrappers agora, porém corre o risco de tomar umNullPointerException.
Você pode fazer o autoboxing diretamente paraObjecttambém, possibilitando passar um tipo primitivo para um método que receberObjectcomo argumento:
Object o = 5;
14.8 - java.lang.String
Stringé uma classe em Java. Variáveis do tipoStringguardam referências a objetos, e não um valor, como acontece com os tipos primitivos.
Aliás, podemos criar umaStringutilizando-nos donew: String x = new String("fj11");
String y = new String("fj11");
Criamos aqui, dois objetos diferentes. O que acontece quando comparamos essas duas referências utili- zando o==?
if (x == y) {
System.out.println("mesmo objeto"); }
else {
System.out.println("objetos diferentes!"); }
Temos aqui dois objetos diferentes! E, então, como faríamos para verificar se o conteúdo do objeto é o mesmo? Utilizamos o métodoequals, que foi reescrito pelaString, para fazer a comparação decharemchar.
if (x.equals(y)) {
System.out.println("consideramos iguais no critério de igualdade"); }
else {
System.out.println("consideramos diferentes no critério de igualdade"); }
Aqui, a comparação retorna verdadeiro. Por quê? Pois quem implementou a classe String decidiu que este seria o melhor critério de comparação. Você pode descobrir os critérios de igualdade de cada classe pela documentação.
Podemos também concatenarStringsusando o+. Podemos concatenarStringscom qualquer outra coisa, até mesmo objetos e números:
int total = 5;
System.out.println("o total gasto é: " + total);
A classeStringconta também com um métodosplit, que divide aStringem um array deStrings, dado determinado critério.
String frase = "java é demais"; String palavras[] = frase.split(" ");
Se quisermos comparar duas Strings, utilizamos o método compareTo, que recebe uma String como ar- gumento e devolve um inteiro indicando se a String vem antes, é igual ou vem depois da String recebida. Se forem iguais, é devolvido 0; se for anterior à String do argumento, devolve um inteiro negativo; e, se for posterior, um inteiro positivo.
Fato importante: umaStringé imutável. O java cria um pool de Strings para usar como cache e, se a String não fosse imutável, mudando o valor de umaStringafetaria todas as Strings de outras classes que tivessem o mesmo valor.
Repare no código abaixo: String palavra = "fj11"; palavra.toUpperCase(); System.out.println(palavra);
Pode parecer estranho, mas ele imprime “fj11” em minúsculo. Todo método que parece alterar o valor de umaString, na verdade, cria uma novaStringcom as mudanças solicitadas e a retorna. O código realmente útil ficaria assim:
String palavra = "fj11";
String outra = palavra.toUpperCase(); System.out.println(outra);
Ou você pode eliminar a criação de outra variável temporária, se achar conveniente: String palavra = "fj11";
palavra = palavra.toUpperCase(); System.out.println(palavra);
Isso funciona da mesma forma paratodos os métodos que parecem alterar o conteúdo de umaString. O funcionamento do pool interno de Strings do java tem uma série de detalhes e você pode encontrar mais informações sobre isto na documentação da classeStringe no seu métodointern().
Outros métodos da classeString
Existem diversos métodos da classeStringque são extremamente importantes. Recomendamos sempre consultar o javadoc relativo a essa classe para aprender cada vez mais sobre a mesma. Por exemplo, o métodocharAt(i), retorna o caractere existente na posiçãoida string, ométodo length retorna o número de caracteres na mesma e o método substringque recebe um inte devolve a SubString a partir da posição passada por aqueleint.
OindexOfrecebe um char ou uma String e devolve o índice em que aparece pela primeira vez na String principal (há também olastIndexOfque devolve o índice da última ocorrência).
OtoUpperCasee otoLowerCasedevolvem uma nova String toda em maiúscula e toda em minúscula, respectivamente.
A partir do Java 6, temos ainda o métodoisEmpty, que devolve true se a String for vazia ou false caso contrário.
Alguns métodos úteis para buscas são ocontainse omatches.
Há muitos outros métodos, recomendamos que você sempre consulte o javadoc da classe.
java.langStringBuffereStringBuilder
Como a classeString é imutável, trabalhar com uma mesmaStringdiversas vezes pode ter um efeito colateral: gerar inúmerasStrings temporárias. Isto prejudica a performance da aplicação consideravelmente.
No caso de você trabalhar muito com a manipulação de uma mesmaString(por exemplo, dentro de um laço), o ideal é utilizar a classeStringBuffer. A classeStringBufferrepresenta uma sequência de caracteres. Diferentemente daString, ela é mutável, e não possui aquele pool.
A classeStringBuildertem exatamente os mesmos métodos, com a diferença dela não serthread- safe. Veremos sobre este conceito no capítulo de Threads.
14.9 - java.lang.Math
Na classe Math, existe uma série de métodos estáticos que fazem operações com números como, por exemplo, arredondar(round), tirar o valor absoluto (abs), tirar a raiz(sqrt), calcular o seno(sin) e outros.
double d = 4.6;
long i = Math.round(d);
int x = -4;
int y = Math.abs(x);
Consulte a documentação para ver a grande quantidade de métodos diferentes. No Java 5.0, podemos tirar proveito doimport staticaqui:
import static java.lang.Math.*;
Isso elimina a necessidade de usar o nome da classe, sob o custo de legibilidade:
double d = 4.6;
long i = round(d);
int x = -4;
int y = abs(x);
14.10 - Exercícios: java.lang
1) Teste os exemplos desse capítulo, para ver que umaStringé imutável. Por exemplo:
public class TestaString {
public static void main(String[] args) { String s = "fj11";
s.replaceAll("1", "2"); System.out.println(s); }
}
Como fazer para ele imprimir fj22?
2) Utilize-se da documentação do Java e descubra de que classe é o objeto referenciado pelo atributooutda System.
Repare que poderíamos escrever: PrintStream saida = System.out; saida.println("ola");
3) Crie e imprima uma referência para Conta (ContaCorrente ou ContaPoupanca, no caso de sua Conta ser abstrata):
Conta conta = new ContaCorrente(): System.out.println(conta);
O que acontece?
4) Reescreva o método toStringda sua classe Conta fazendo com que uma mensagem mais propícia seja devolvida. Lembre-se de aproveitar dos recursos do Eclipse para isto: digitando apenas o começo do nome do método a ser reescrito e pressionandoCtrl+espaço, ele vai sugerir reescrever o método, poupando você do trabalho de escrever a assinatura do mesmo, e de cometer algum engano.
public abstract class Conta {
private double saldo;
public String toString() {
return "esse objeto é uma conta com saldo R$" + this.saldo; }
// restante da classe }
Agora imprima novamente uma referência aConta. O que aconteceu?
5) Reescreva o método equalsda classe Contapara que duas contas com o mesmo número de conta sejam consideradas iguais. Esboço:
abstract class Conta {
private int numero;
public boolean equals(Object obj) { Conta outraConta = (Conta) obj;
return this.numero == outraConta.numero; }
// restante }
Compare duas instâncias deContacom==, depois comequals, sendo que as instâncias são diferentes mas possuem o mesmo número.
6) Um doublenão está sendo suficiente para guardar a quantidade de casas necessárias em uma aplicação. Preciso guardar um número decimal muito grande! O que poderia usar? (consulte a documentação, tente adivinhar onde você pode encontrar algo desse tipo pelos nomes dos pacotes, veja como é intuitivo). 7) (opcional) Agora faça com que o equals da sua classe Conta também leve em consideração a String do
nome do cliente a qual ela pertence. Teste-a.
8) (opcional) Crie oGuardadorDeObjetosvisto nesse capítulo, coloque umaContaPoupancana primeira posição, e tente recuperar essa conta fazendo um casting paraContaCorrente:
9) (opcional) Crie a classe GuardadorDeObjetos desse capítulo. Teste-a adicionando uma ContaCorrente e depois devolvendo comoContaPoupanca, usando casting. Repare na exception que é lançada:
GuardadorDeObjetos guardador = new GuardadorDeObjetos(); ContaCorrente cc = new ContaCorrente();
guardador.adicionaObjeto(cc); // vai precisar do casting
// Ctrl+1 pro Eclipse gerar para você ContaPoupanca cp = guardador.pega(0);
Teste também o autoboxing do java 5.0, passando um inteiro para nosso guardador.
10) (opcional) Escreva um método que usa os métodoscharAtelengthde umaStringpara imprimir a mesma caractere a caractere, com cada caractere em uma linha diferente.
11) (opcional) Reescreva o método do exercício anterior, mas agora imprima a string de trás para a frente. 12) (opcional) Pesquise a classeStringBuilder(ou StringBuffer no java 1.4). Ela é mutável. Por que usá-la em
vez daString? Quando usá-la?
14.11 - Desafio
1) Converta umaStringpara um número sem usar as bibliotecas do java que já fazem isso. Isso é, umaString x = “762"
deve gerar umint i = 762.
Para ajudar, saiba que um char pode ser “transformado” em int com o mesmo valor numérico fazendo:
char c = ’3’;
int i = c - ’0’; // i vale 3!
Aqui estamos nos aproveitando do conhecimento da tabela unicode: os números de 0 a 9 estão em sequen- cia! Você poderia usar o método estáticoCharacter.getNumericValue(char)em vez disso.
Pacote java.io
“A benevolência é sobretudo um vício do orgulho e não uma virtude da alma.” –Doantien Alphonse François (Marquês de Sade)
Ao término desse capítulo, você será capaz de:
• ler e escrever bytes, caracteres e Strings de/para a entrada e saída padrão; • ler e escrever bytes, caracteres e Strings de/para arquivos;
• utilizar buffers para agilizar a leitura e escrita através de fluxos; • usar Scanner e PrintStream.
15.1 - Conhecendo uma API
Vamos passar, agora, a conhecer APIs do Java. java.ioejava.utilpossuem as classes que você mais comumente vai usar, não importando se seu aplicativo é desktop, web, ou mesmo para celulares.
Apesar de ser importante conhecer nomes e métodos das classes mais utilizadas, o interessante aqui é que você enxergue que todos os conceitos previamente estudados são aplicados a toda hora nas classes da biblioteca padrão.
Não se preocupe em decorar nomes. Atenha-se em entender como essas classes estão relacionadas e como elas estão tirando proveito do uso de interfaces, polimorfismo, classes abstratas e encapsulamento. Lembre-se de estar com a documentação (javadoc) aberta durante o contato com esses pacotes.
Veremos também threads e sockets em capítulos posteriores, que ajudarão a condensar nosso conheci- mento, tendo em vista que no exercício de sockets utilizaremos todos conceitos aprendidos, juntamente com as várias APIs.