Este artigo visa auxiliar em entrevistas focadas em conceitos fundamentais de Java. Continue acompanhando para atualizações.
1) Por que a classe String é imutável em Java?
A imutabilidade da String em Java é fundamental por diversas razões:
- Segurança: Uma vez criada, o conteúdo de uma String não pode ser alterado. Isso é crucial para operações sensíveis, como senhas ou chaves de segurança, pois previne modificações acidentais durante o uso.
- Segurança em Threads: A imutabilidade simplifica o gerenciamento em ambientes concorrentes. Múltiplas threads podem acessar uma String simultaneamente sem o risco de que seu conteúdo seja modificado por outra thread.
- Cache de Hash Code: O valor de hash de uma String pode ser calculado e armazenado em cache na criação, pois ele nunca mudará. Isso otimiza o desempenho em cenários que exigem cálculos frequentes de hash.
- String Pool: Como as Strings são imutáveis, elas podem ser armazenadas em um pool de Strings (String Pool) para reutilização. Isso economiza memória e melhora a performance geral.
2) A classe String é realmente imutável?
Embora o design da classe String seja para ser imutável, é tecnicamente possível modificar seu conteúdo em tempo de execução utilizando reflexão (reflection). No entanto, esta prática é fortemente desencorajada, pois viola o princípio de design da imutabilidade e pode levar a comportamentos imprevisíveis e erros difíceis de depurar.
3) É possível herdar da classe String?
Não, a classe String em Java é declarada como final, o que impede sua herança por outras classes. A palavra-chave final garante que a classe String e seu comportamento imutável não possam ser alterados por subclasses. Se funcionalidades adicionais de manipulação de strings forem necessárias, classes como StringBuilder ou StringBuffer devem ser utilizadas.
4) Arrays possuem o método length()?
Não, arrays em Java não possuem um método chamado length(). Em vez disso, eles possuem um atributo público chamado length que armazena o número de elementos do array. Este atributo é acessado diretamente, sem a necessidade de parênteses.
int[] meuArray = {10, 20, 30, 40, 50};
int tamanho = meuArray.length;
System.out.println("O tamanho do array é: " + tamanho);
5) A classe String possui o método length()?
Sim, a classe String possui um método chamado length() que retorna o número de caracteres na string.
String minhaString = "Exemplo de String";
int comprimento = minhaString.length();
System.out.println("O comprimento da string é: " + comprimento);
6) Quais são os métodos mais comuns da classe String?
A classe String oferece uma variedade de métodos úteis para manipulação de texto:
length(): Retorna o número de caracteres.charAt(int indice): Retorna o caractere na posição especificada.substring(int indiceInicio): Retorna uma sub-string a partir do índice inicial até o final.substring(int indiceInicio, int indiceFim): Retorna uma sub-string entre os índices inicial e final.indexOf(String str): Retorna o índice da primeira ocorrência de uma sub-string.indexOf(String str, int indiceInicio): Retorna o índice da primeira ocorrência de uma sub-string a partir de um índice especificado.lastIndexOf(String str): Retorna o índice da última ocorrência de uma sub-string.lastIndexOf(String str, int indiceFim): Retorna o índice da última ocorrência de uma sub-string a partir de um índice especificado (contando de trás para frente).startsWith(String prefixo): Verifica se a string começa com um determinado prefixo.endsWith(String sufixo): Verifica se a string termina com um determinado sufixo.toLowerCase(): Converte todos os caracteres da string para minúsculas.toUpperCase(): Converte todos os caracteres da string para maiúsculas.trim(): Remove espaços em branco no início e no final da string.replace(char oldChar, char newChar): Substitui todas as ocorrências de um caractere por outro.
7) Quais as vantagens de usar String como chave em um HashMap?
Utilizar String como chave em um HashMap traz benefícios importantes:
- Imutabilidade e Hash Code: Como Strings são imutáveis, seu valor de hash é constante após a criação. Isso garante que a chave permaneça válida no
HashMap, evitando problemas de busca e recuperação. - Cache de Hash Code: A classe String pré-calcula e armazena em cache seu valor de hash. O
HashMappode aproveitar esse cache, otimizando a performance de operações comoputeget. - Legibilidade: Strings como chaves são fáceis de ler e entender, facilitando a depuração e a manutenção do código.
8) Qual a diferença entre String, StringBuffer e StringBuilder? Por que String é imutável?
- String: É imutável. Qualquer operação que pareça modificar uma String, na verdade, cria uma nova instância de String. A imutabilidade é adotada por razões de segurança (evitar modificações não intencionais), segurança em threads (múltiplas threads podem acessar sem conflito) e otimização de performance (cache de hash code e String Pool).
- StringBuffer: É mutável e thread-safe. Métodos que modificam o conteúdo são sincronizados, garantindo que operações em ambientes concorrentes sejam seguras, mas com um custo de performance.
- StringBuilder: É mutável e não é thread-safe. É mais rápido que
StringBufferem cenários de thread única, pois não possui a sobrecarga da sincronização.
Em resumo, a imutabilidade da String prioriza segurança e simplicidade em contextos onde o conteúdo não precisa ser alterado dinamicamente.
9) O que é "unboxing" (desembrulhar)? Qual a diferença entre int e Integer?
Unboxing é o processo de converter um objeto de uma classe de empacotamento (wrapper class) para seu tipo de dado primitivo correspondente. Por exemplo, converter um objeto Integer para um valor int.
Diferenças entre int e Integer:
- Tipo:
inté um tipo primitivo;Integeré uma classe (wrapper). - Valer Padrão: O valor padrão para
inté0; o valor padrão paraInteger(quando não inicializado) énull. - Objetos e Performance:
Integeré um objeto, e o processo de unboxing para obter um valorintpode introduzir uma pequena sobrecarga de performance. Usarintdiretamente é geralmente mais eficiente. - Uso:
inté ideal para cálculos numéricos diretos.Integeré necessário quando se trabalha com coleções genéricas (comoArrayList<Integer>) ou quando um tipo primitivo precisa ser tratado como um objeto.
10) Integer a = 127 e Integer b = 127 são iguais?
Sim, em Java, para valores de Integer entre -128 e 127 (inclusive), a JVM utiliza um cache. Isso significa que, quando você cria dois objetos Integer com valores dentro dessa faixa, ambos os identificadores (a e b) apontarão para a mesma instância na memória. Portanto, a comparação a == b retornará true.
Integer a = 127;
Integer b = 127;
System.out.println(a == b); // Saída: true
No entanto, se o valor estiver fora dessa faixa de cache (por exemplo, 128 ou maior), novas instâncias de Integer serão criadas, e a comparação == retornará false, pois os identificadores apontarão para objetos diferentes na memória.
Integer c = 128;
Integer d = 128;
System.out.println(c == d); // Saída: false