
39. Quais são os modificadores de acesso em Java? Nomeie-os. Para que são usados?
Anteriormente, abordei modificadores de acesso em uma pergunta sobre os elementos de Java usados para obter o encapsulamento. Mas ainda assim, vou lembrá-lo. Modificadores de acesso em Java são palavras-chave que descrevem o nível de acesso concedido a um componente Java específico. Existem os seguintes modificadores de acesso:- público — um elemento marcado com este modificador é público. Em outras palavras, campos e métodos e classes declaradas com o modificador public são visíveis para outras classes tanto em seu próprio pacote quanto em pacotes externos;
- protegido — um elemento marcado com este modificador é acessível de qualquer lugar em sua própria classe no pacote atual ou em classes derivadas, mesmo que estejam em outros pacotes;
- default (ou nenhum modificador) se aplica implicitamente quando nenhum modificador de acesso é indicado. É semelhante ao anterior, exceto que é visível em classes derivadas encontradas em outros pacotes;
- private — este é o mais privado de todos os modificadores. Permite acesso a um elemento apenas dentro da classe atual.
40. Cite os principais recursos dos métodos estáticos e não estáticos
A principal diferença é que os métodos estáticos pertencem a uma classe. Na verdade, você não precisa criar uma instância desta classe — métodos estáticos podem ser chamados apenas a partir do tipo de classe. Por exemplo, suponha que temos um método estático para acariciar um gato:
public class CatService {
public static void petTheCat(Cat cat) {
System.out.println("Pet the cat: " + cat.getName());
}
Não precisamos de uma instância da classe CatService para chamá-lo:
Cat cat = new Cat(7, "Bobby");
CatService.petTheCat(cat);
Por outro lado, os métodos comuns estão vinculados (pertencem) a um objeto. Para chamá-los, você deve ter uma instância (objeto) na qual o método será chamado. Por exemplo, suponha que nosso gato tenha um método não estático meow() :
class Cat {
public void meow() {
System.out.println("Meow! Meow! Meow!");
}
Para chamar esse método, precisamos de uma instância específica de um gato:
Cat cat = new Cat(7, "Bobby");
cat.meow();
41. Quais são as principais restrições aplicáveis aos métodos estáticos e não estáticos?
Como eu disse anteriormente, a principal limitação de um método comum (não estático) é que sempre deve haver alguma instância na qual o método é chamado. Mas um método estático não exige isso. Além disso, um método estático não pode usar a referência this para elementos de um objeto, pois agora existe um objeto atual para o método.42. O que significa a palavra-chave estática? Um método estático pode ser substituído ou sobrecarregado?
Um elemento marcado com a palavra-chave static não pertence a uma instância de uma classe, mas sim à própria classe. Ele é carregado quando a própria classe é carregada. Os elementos estáticos são os mesmos para todo o programa, enquanto os elementos não estáticos são os mesmos apenas para um objeto específico. Os seguintes elementos podem ser estáticos:- campos de uma classe;
- bloco de inicialização de uma classe;
- um método de uma classe;
- classes aninhadas de uma classe (é claro, isso também é uma tautologia).
43. Um método pode ser estático e abstrato ao mesmo tempo?
Já respondi isso em artigo anterior: um método não pode ser abstrato e estático ao mesmo tempo. Se um método for abstrato, isso implica que ele deve ser substituído em uma classe filha. Mas um método estático pertence à classe e não pode ser substituído. Isso cria uma contradição, que o compilador notará e ficará chateado. Se você se encontrar nesta situação, você deve pensar seriamente sobre a correção da arquitetura do seu aplicativo (dica: algo está claramente errado com ele).
44. Os métodos estáticos podem ser usados no meio de métodos não estáticos? E vice versa? Por que?
Podemos usar métodos estáticos em métodos não estáticos. Nada impede isso. Dito isto, o oposto não é possível: um método estático não pode usar um método não estático sem fazer referência a uma instância específica da classe. Lembre-se, membros estáticos de uma classe não têm acesso a uma referência this : você pode ter quantos objetos concretos da classe desejar, e cada um deles conterá uma referência this , que é uma auto-referência. Então, como determinar qual referência usar? Uh, você não. É por isso que os elementos estáticos não podem referir-se aos não estáticos sem uma referência a um objeto específico. Basicamente, um método estático só pode usar um método não estático se tiver uma referência a um objeto específico. Por exemplo, aquele que veio como argumento de método:
public static void petTheCat(Cat cat) {
System.out.println("Pet the cat: " + cat.getName());
}
Aqui vemos que no método estático petTheCat() chama getName , um método não estático comum de um objeto Cat .
45. O que é uma interface? Pode haver uma interface final?
Lembraremos que Java não possui herança múltipla. As interfaces são uma espécie de alternativa a isso. Uma interface é como uma classe muito simplificada. Eles definem funcionalidade, mas não uma implementação concreta. Essa tarefa é deixada para as classes que implementam essas interfaces. Exemplo de interface:
public interface Animal {
void speak();
}
Exemplo de implementação de interface por uma classe
class Cat implements Animal {
@Override
public void speak() {
System.out.println("Meow! Meow! Meow!");
}
}
Aqui está o que é importante saber sobre o uso de interfaces:
-
Os métodos de interface devem conter apenas um cabeçalho. Eles não devem ter um corpo de método específico, ou seja, devem ser abstratos (embora não utilizem a palavra-chave abstract ). Existem exceções: métodos estáticos e métodos padrão, que requerem um corpo de método.
-
Uma classe pode implementar muitas interfaces (como eu disse, interfaces são uma alternativa à herança múltipla). Os nomes das interfaces são separados por vírgulas no cabeçalho do método: class Lion implements Animal, Wild .
-
As interfaces são criadas usando a palavra-chave interface .
-
Quando uma classe implementa uma interface, usamos a palavra-chave implements .
-
Uma classe que implementa uma determinada interface deve implementar todos os seus métodos abstratos ou deve declarar-se abstrata.
-
O principal objetivo do uso de interfaces é implementar polimorfismo (para dar a um objeto a capacidade de assumir muitas formas).
-
Como regra, os modificadores de acesso para métodos não são indicados nas interfaces: eles são públicos por padrão e você não pode especificar outros modificadores além de public . A partir do Java 9, você pode usar modificadores privados em métodos.
-
Por padrão, as variáveis de interface são static final . Em outras palavras, são constantes — devem sempre ser inicializadas diretamente na interface.
-
Você não pode criar uma instância de uma interface.

46. Onde os campos estáticos podem ser inicializados?
Campos estáticos podem ser inicializados:- imediatamente após a declaração, usando sinal de igual ( = );
- em um bloco de inicialização estático;
- em um bloco de inicialização não estático (mas você precisa entender que toda vez que um objeto é criado, o campo estático será sobrescrito quando este bloco de inicialização for executado;
- em um construtor de classe. Cada vez que o construtor é chamado (ou seja, cada vez que um objeto é criado usando este construtor), o campo será sobrescrito;
- em métodos estáticos;
- em métodos não estáticos;
- em classes aninhadas estáticas e não estáticas, locais e anônimas.
47. O que são aulas anônimas?
Classes anônimas são classes que não possuem tipo próprio. Do que estou falando? Quando falamos sobre interfaces, mencionei que não é possível criar uma instância de um objeto: você só pode criar uma instância de uma classe que implemente uma interface. E se você não quiser que alguma classe implemente uma interface, mas precisar de um objeto que implemente a interface? E é provável que este seja o único uso do objeto. E você não precisa criar uma classe de implementação completa. Como você faria? Isso mesmo! Usando uma classe anônima!
public final interface Animal {
public void speak();
}
Se quisermos usar uma classe anônima para instanciar uma determinada interface:
Animal cat = new Animal() {
@Override
public void speak() {
System.out.println("Meow! Meow! Meow!");
}
};
E então, você pode usar este objeto com segurança e seu método speak() implementado . Em outras palavras, a classe anônima implementa a interface e todos os seus métodos abstratos, aqui e agora. Caso contrário, não seríamos capazes de criar um objeto de interface/classe abstrata, pois haveria métodos não implementados/abstratos. Como mencionei, as classes anônimas são usadas não apenas para implementar os métodos abstratos de uma interface, mas também para implementar os métodos abstratos de uma classe abstrata. Essa abordagem é boa para situações em que um objeto é usado uma vez ou quando a implementação de um determinado método é necessária apenas uma vez. Não há necessidade de criar uma classe separada que implemente a classe/interface abstrata necessária. Mas também observo que classes anônimas raramente são usadas no trabalho. Via de regra, as aulas normais ainda têm preferência. Você pode ler mais sobre classes anônimas aqui neste artigo
.
48. O que são classes primitivas?
Acho que esta é uma pergunta enganosa, possivelmente uma pegadinha, já que Java não possui classes primitivas. Existe apenas o conceito de tipos primitivos, que consideramos anteriormente. Lembramos que Java possui 8 tipos primitivos: byte , short , int , long , float , double , char , boolean .49. O que é uma classe wrapper?
O principal problema com o uso de tipos primitivos em Java é que eles não são classes e Java é uma linguagem OOP. Ou seja, os programas escritos nesta linguagem equivalem a interações entre objetos. Mas os primitivos não são objetos. Eles não possuem métodos, mesmo os métodos padrão da classe Object . Mas e se precisarmos usar um primitivo como chave em um Map ? Então precisamos chamar seu método hashCode() . Você também pode chamar seu método equals() lá. E então? Há muitos momentos em que você precisa de uma aula, não de um primitivo. Isso torna os elementos primitivos inutilizáveis e indesejáveis em um programa porque violam a própria ideia de OOP. Mas a situação não é tão ruim quanto parece. Afinal, Java possui o conceito de wrappers primitivos. Em Java, todo tipo primitivo possui um gêmeo – uma classe wrapper.- byte -> Byte.class
- curto -> Curto.class
- int -> Inteiro.class
- longo -> Long.class
- flutuar -> Float.class
- duplo -> Duplo.class
- char -> Personagem.class
- booleano -> Boolean.class

50. O que é uma classe aninhada? Onde é usado?
Uma classe aninhada é uma classe que é membro de outra classe. Existem 4 tipos dessas classes aninhadas em Java: 1. Classe interna Este tipo de classe é declarado diretamente no corpo de outra classe. Uma classe interna é uma classe aninhada não estática e pode acessar qualquer campo privado ou método de instância da classe externa. Como exemplo, vamos criar um zoológico que contenha um animal — uma zebra:
public class Zoo {
class Zebra {
public void eat(String food) {
System.out.println("Zebra eats " + food);
}
}
}
Não é complicado, certo? Vamos dar uma olhada em um exemplo de criação de uma instância da classe interna:
Zoo.Zebra zebra = new Zoo().new Zebra();
zebra.eat("apple");
Como você já viu, é necessário primeiro criar um objeto da classe envolvente. Então você usa a referência do objeto para criar uma instância da classe interna. Gostaria também de salientar que uma classe interna (classe aninhada não estática) não pode ter métodos estáticos ou campos estáticos. Isso ocorre precisamente porque a classe interna está implicitamente associada a uma instância de sua classe externa e, portanto, não pode declarar nenhum método estático dentro dela mesma. 2. Classes aninhadas estáticas Essas classes são semelhantes à categoria anterior, mas possuem o modificador de acesso estático na declaração da classe. Como esse tipo de classe não tem acesso aos campos não estáticos da classe externa, ela se parece mais com uma parte estática da classe externa do que com uma classe interna. Mas esta classe tem acesso a todos os membros estáticos da classe externa, mesmo os privados. Exemplo de uma classe aninhada estática:
public class Zoo {
static class Zebra {
public void eat(String food) {
System.out.println("Zebra eats " + food);
}
}
}
É criado de uma forma ligeiramente diferente do anterior:
Zoo.Zebra zebra = new Zoo.Zebra();
zebra.eat("apple");
Aqui não precisamos de um objeto da classe externa para criar um objeto da classe estática aninhada. Precisamos apenas saber o nome da classe aninhada para encontrá-la na classe externa. 3. Classes locais Classes locais são classes declaradas dentro do corpo de um método. Objetos de uma classe local podem ser criados e usados somente dentro do método envolvente. Exemplo:
public class Zoo {
public void feed(String animal, String food) {
switch(animal) {
case "zebra":
class Zebra {
public void eat(String food) {
System.out.println("Zebra eats " + food);
}
}
Zebra zebra = new Zebra();
zebra.eat(food);
...
Aqui está um exemplo:
Zoo zoo = new Zoo();
zoo.feed("zebra", "apple");
Se você não visse o código do método feed() , você nem suspeitaria que existe uma classe local, não é? Uma classe local não pode ser estática ou transiente , mas pode ser marcada como abstrata ou final (uma OU a outra, mas não ambas, pois o uso simultâneo desses dois modificadores cria um conflito). 4. Classes anônimas Já falamos sobre classes anônimas acima e, como você deve se lembrar, elas podem ser criadas a partir de duas fontes — interfaces e classes. Razões para usá-las Classes estáticas e não estáticas aninhadas são usadas porque às vezes é melhor incorporar classes pequenas em classes mais gerais e mantê-las juntas para que tenham maior coesão e um propósito comum. Basicamente, as classes aninhadas permitem aumentar o encapsulamento do seu código. Você pode optar por usar uma classe local se a classe for usada exclusivamente em um único método. Nesse caso, precisamos espalhar o código pela aplicação? Não. Dito isto, acrescentarei que na minha experiência nunca vi ninguém usar classes locais, porque se elas são necessárias ou não é altamente controverso. Você pode usar classes anônimas quando uma implementação específica de uma interface ou classe abstrata for necessária apenas uma vez. Nesse caso, não há necessidade de criar uma classe separada e completa com uma implementação. Em vez disso, mantivemos tudo simples e implementamos o(s) método(s) necessário(s) usando uma classe anônima, usamos o objeto e depois esquecemos dele (é claro, o coletor de lixo não esqueceu). Sua compreensão das classes aninhadas será aprimorada com este artigo.
51. Quais modificadores de acesso uma classe pode ter?
Existem diferentes tipos de classes e diferentes modificadores de acesso se aplicam a elas:- uma classe externa pode ter o modificador de acesso público ou nenhum modificador (o modificador padrão);
- uma classe interna (classe aninhada não estática) pode ter qualquer um dos 4 modificadores de acesso;
- uma classe estática aninhada pode ter qualquer um dos modificadores de acesso, exceto protected , porque esse modificador implica herança, o que contradiz qualquer membro estático da classe (membros estáticos não são herdados);
- uma classe local só pode ter o modificador padrão (ou seja, nenhum modificador);
- uma classe anônima não possui declaração de classe, portanto não possui nenhum modificador de acesso.

GO TO FULL VERSION