¡Hola hola! Hoy en día, los desarrolladores de Java tienen una gran demanda. Por supuesto, no puedo ofrecerle una vacante, pero intentaré ayudarlo a adquirir nuevos conocimientos y cerrar algunas brechas. Por eso, continuamos analizando más de 250 preguntas de entrevista para desarrolladores de Java. Los enlaces a partes anteriores del análisis se encuentran al final del artículo.
39. ¿Qué son los modificadores de acceso en Java? Nómbralos. ¿Para qué se usan?
Anteriormente describí los modificadores de acceso en la pregunta sobre los elementos de encapsulación de Java. Pero te lo recordaré de todos modos. Los modificadores de acceso en Java son palabras clave que describen el nivel de acceso otorgado a un componente Java en particular. Los modificadores de acceso pueden ser:- público : un elemento con este modificador será accesible públicamente. Aquellos. los campos y métodos, las clases declaradas con el modificador público son visibles para otras clases tanto desde el paquete actual como desde paquetes externos;
- protegido : se podrá acceder a un elemento con este modificador desde cualquier lugar en la clase actual del paquete actual o en clases descendientes, incluso si están en otros paquetes;
- default o modificador faltante: este modificador se usa implícitamente cuando el modificador de acceso no se especifica en absoluto. Es similar al anterior, excepto que se permite visibilidad en clases descendientes que están en otros paquetes;
- privado es el más privado de todos los modificadores, permitiendo el acceso al elemento sólo dentro de la clase actual.
40. Nombra la característica principal de los métodos estáticos y variables.
Una formulación muy extraña: "métodos variables". Seguramente esto se refiere a métodos ordinarios y no estáticos. Entonces, la principal diferencia es que los métodos estáticos pertenecen a la clase y, de hecho, para ellos no es necesario crear una instancia de esta clase: solo se puede llamar usando el tipo de clase. Por ejemplo, tenemos un método estático para acariciar al gato:public class CatService {
public static void petTheCat(Cat cat) {
System.out.println("Погладить кота - " + cat.getName());
}
No necesitamos una instancia de la clase CatService para llamarlo :
Cat cat = new Cat(7, "Bobi");
CatService.petTheCat(cat);
Mientras que los métodos ordinarios están vinculados (pertenecen a) un objeto y, para poder llamarlos, debe tener una instancia (objeto) en la que se llamará el método. Por ejemplo, un gato tiene un método no estático: maullar:
class Cat {
public void mew() {
System.out.println("Meow! Meow! Meow!");
}
Para llamar a este método, necesitamos una instancia específica del gato:
Cat cat = new Cat(7, "Bobi");
cat.mew();
41. ¿Cuáles son las principales restricciones a los métodos estáticos y “variables”?
Como dije antes, la principal limitación de un método regular es que siempre debe haber alguna instancia en la que se llamará a este método. Pero un método estático no requiere esto, pero no puede hacer referencia a esta referencia (a los elementos del objeto actual) ya que el objeto actual no existe para él.42. ¿Qué significa la palabra clave estática? ¿Se puede anular o sobrecargar un método estático?
Un elemento designado por la palabra clave estática no pertenece a un objeto de la clase, sino a la clase, y se carga cuando se carga la clase misma. Los elementos estáticos son los únicos para todo el programa y los elementos regulares son los únicos para un objeto específico. La estática puede ser:- campos de clase;
- bloque de inicialización de clase;
- método de clase;
- clases internas de una clase (sin embargo, eso sigue siendo una tautología).
43. ¿Puede un método ser estático y abstracto al mismo tiempo?
Ya lo mencioné en el artículo anterior: un método no puede ser abstracto y estático al mismo tiempo. El carácter abstracto de un método significa que debe anularse en el sucesor. Al mismo tiempo, un método estático pertenece a la clase y no se puede anular: esto provocará una contradicción, que el compilador verá y empezará a maldecir. Si se encuentra en una situación así, debería pensar seriamente en la corrección de la arquitectura de su aplicación (después de todo, claramente hay algo mal en ella).44. ¿Es posible utilizar métodos estáticos en medio de los habituales? ¿Viceversa? ¿Por qué?
Los métodos estáticos se pueden utilizar en los habituales, ya que nada lo impide. Al mismo tiempo, la situación inversa es imposible: un método estático no puede utilizar un método normal sin tener una referencia a una instancia específica de esta clase. Y como recordamos, esta referencia no está disponible para miembros de clases estáticas: puede haber tantos objetos específicos de la clase como desee, y cada uno de ellos tendrá una referencia a sí mismo en su interior: this . ¿Y cómo entiendes entonces cuál es el enlace en particular que debes tomar? Pero de ninguna manera. Por tanto, los elementos estáticos no pueden hacer referencia a los no estáticos, sin una referencia a un objeto específico. En realidad, un método estático puede utilizar un método no estático sólo si tiene una referencia a un objeto específico. Por ejemplo, el que vino como argumento:public static void petTheCat(Cat cat) {
System.out.println("Погладить кота - " + cat.getName());
}
Aquí vemos que el método estático petTheCat llama al método normal no estático del objeto Cat : getName .
45. ¿Qué es la interfaz? ¿Puede haber una interfaz final?
Como recordamos, no existe herencia múltiple en Java. Las interfaces son una especie de alternativa. La interfaz parece una clase muy simplificada. Definen la funcionalidad sin una implementación específica, que es implementada por clases que implementan (implementan) estas interfaces. Ejemplo de interfaz:public interface Animal {
void voice();
}
Un ejemplo de implementación de interfaz por parte de una clase:
class Cat implements Animal {
@Override
public void voice() {
System.out.println("Meow! Meow! Meow!");
}
}
Lo principal que necesita saber sobre el uso de interfaces es:
- Los métodos de interfaz deben contener sólo un encabezado, sin un cuerpo de método específico, es decir. debe ser abstracto (pero sin utilizar la palabra clave abstracta ). La excepción a esto son los métodos estáticos y predeterminados, que requieren un cuerpo de método.
- Una clase puede implementar muchas interfaces (como dije, esta es una alternativa a la herencia múltiple), que se escriben separadas por comas: clase Lion implements Animal, Wild .
- Las interfaces se crean utilizando la palabra clave- interfaz .
- Al implementar una interfaz mediante una clase, la palabra clave es implements .
- Una clase que implementa una interfaz particular debe implementar todos sus métodos abstractos o debe declararse abstracta.
- El objetivo principal del uso de interfaces es implementar polimorfismo (la capacidad de los objetos de adoptar muchas formas).
- Como regla general, los modificadores de acceso a los métodos no están escritos en la interfaz: son públicos por defecto y no se pueden especificar otros modificadores que no sean públicos . Desde Java 9, puedes usar modificadores privados para los métodos.
- Las variables de la interfaz son estáticas finales por defecto , en otras palabras, constantes: siempre deben inicializarse directamente en la interfaz.
- No puede crear un objeto de interfaz.
46. ¿Dónde puedo inicializar campos estáticos?
Los campos estáticos se pueden inicializar:- directamente al momento de la declaración, mediante el signo igual = ;
- en el bloque de inicialización estática;
- en un bloque de inicialización no estático, pero debe comprender que cada vez que se crea un objeto, este bloque de inicialización sobrescribirá este campo;
- en el constructor de clases. Cada vez que se llama a este constructor (es decir, cuando se crea un objeto a través de este constructor), este campo se sobrescribirá;
- en métodos estáticos;
- en métodos no estáticos;
- en clases internas estáticas y no estáticas, locales y anónimas.
47. ¿Qué son las clases anónimas?
Las clases anónimas son clases que no tienen su propio tipo. ¿De qué estoy hablando? Cuando hablamos de interfaces, mencioné que no puedes crear un objeto de interfaz: solo puedes crear un objeto de una clase que implemente la interfaz. ¿Qué sucede si no desea implementar una interfaz en una clase, pero aún necesita un objeto del tipo de interfaz? Y lo más probable es que este sea un caso único de uso de este objeto. Y no es necesario crear una clase de implementación completa. ¿Cómo harás ésto? ¡Bien! ¡A través de una clase anónima! Digamos que tenemos alguna interfaz Animal :public final interface Animal {
public void voice();
}
Si queremos crear una instancia de esta interfaz a través de una clase anónima:
Animal cat = new Animal() {
@Override
public void voice() {
System.out.println("Meow! Meow! Meow!");
}
};
Y luego podrá utilizar de forma segura este objeto y su método implementado: voz . Es decir, una clase anónima implementa esta interfaz y todos sus métodos abstractos aquí y ahora. De lo contrario, no podremos crear una interfaz/objeto de clase abstracta, ya que hay métodos abstractos/no implementados. Como mencioné, las clases anónimas se usan no solo para implementar métodos abstractos de una interfaz, sino también para implementar métodos abstractos de una clase abstracta. Este enfoque es bueno para situaciones en las que un objeto se usa una sola vez o se necesita una implementación determinada de métodos solo una vez, y no hay necesidad de crear una clase separada que implementará la clase/interfaz abstracta requerida. Pero también señalaré que el uso de clases anónimas es poco común en el trabajo: por regla general, todavía se da preferencia a las clases ordinarias. Puedes leer más sobre las clases anónimas en este artículo .
48. ¿Qué son las clases primitivas?
En lo que a mí respecta, esta es una pregunta muy extraña y, tal vez, una pregunta trampa, porque en Java no existen las clases primitivas: excepto quizás el concepto de tipos primitivos, que ya hemos considerado anteriormente. Como recordamos, hay 8 tipos primitivos en Java: byte , short , int , long , float , double , char , boolean .49. ¿Qué es la clase “envoltorio”?
El principal problema con el uso de tipos primitivos en Java es que todavía no son clases y Java sigue siendo un lenguaje OOP. Es decir, los programas escritos en este lenguaje se reducen a la interacción entre objetos. Bueno, los primitivos no son objetos. No tienen métodos, ni siquiera los estándar de la clase Object . Bueno, ¿qué pasaría si necesitáramos usar una primitiva como clave en Map ? Entonces necesitas llamar al método hashCode . También puedes llamar al método igual allí . ¿Entonces que? Puede haber muchísimos momentos en los que debería haber una clase, y no una primitiva, lo que convierte a las primitivas en elementos no utilizados e indeseables en el programa, porque esto destruye la idea misma de POO. Pero no todo es tan malo como parece. Después de todo, Java tiene el concepto de contenedor primitivo. Cada tipo primitivo tiene una clase analógica:- byte -> Byte.clase
- corto -> Clase corta
- int -> Entero.clase
- largo -> Clase larga
- flotador -> Flotador.clase
- doble -> Doble.clase
- char -> Carácter.clase
- booleano -> booleano.clase
50. ¿Qué es la clase anidada? ¿Cuándo se utiliza?
Una clase anidada es una clase interna que es miembro de otra clase. En Java, existen 4 tipos de clases internas: 1. Clase interna Este tipo de clase se declara directamente en el cuerpo de otra clase. Una clase interna anidada puede acceder a cualquier campo o método privado de una instancia de la clase externa. Como ejemplo, creemos un zoológico en el que tendremos un animal: una cebra:public class Zoo {
class Zebra {
public void toFeed(String food) {
System.out.println("Дать зебре - " + food);
}
}
}
Nada complicado, ¿verdad? Echemos un vistazo a un ejemplo de creación de un objeto de clase interna:
Zoo.Zebra zebra = new Zoo().new Zebra();
zebra.toFeed("яблоко");
Como ya ha visto, es imperativo crear un objeto de la clase de marco, en función de cuya referencia se puede crear un objeto de la clase interna. También me gustaría señalar que una clase interna anidada no puede tener métodos o campos estáticos. Esto se debe a que una clase interna está implícitamente asociada con el objeto de su clase externa y no puede declarar ningún método estático dentro de sí misma. 2. Clases anidadas estáticas Esta clase es similar a la anterior, solo que tiene un modificador de acceso estático cerca de la declaración de clase. Dado que este tipo de clase no tiene acceso a campos no estáticos de la clase externa, se parece más a la parte estática de la clase externa que a una clase interna. En este caso, los datos de la clase tienen acceso a todos los miembros estáticos de la clase externa, incluso a los privados. Ejemplo de una clase anidada estática:
public class Zoo {
static class Zebra {
public void toFeed(String food) {
System.out.println("Дать зебре - " + food);
}
}
}
El método de creación es ligeramente diferente al anterior:
Zoo.Zebra zebra = new Zoo.Zebra();
zebra.toFeed("яблоко");
Aquí no necesitamos un objeto de una clase externa para crear un objeto de una clase estática anidada. De la clase externa, solo necesitamos su tipo para poder encontrar la ubicación de la clase anidada. 3. Clases locales Las clases locales son clases declaradas dentro del cuerpo de un método, y la creación y uso de un objeto de una clase local sólo es posible dentro de este método. Ejemplo:
public class Zoo {
public void toFeed(String animal, String food) {
switch(animal){
case "зебра":
class Zebra {
void toFeedZebra(String food) {
System.out.println("Дать зебре - " + food);
}
}
Zebra zebra = new Zebra();
zebra.toFeedZebra(food);
...
Ejemplo de uso:
Zoo zoo = new Zoo();
zoo.toFeed("зебра", "яблоко");
Sin ver el código del método toFeed , ni siquiera sospecharías la existencia de una clase local, ¿verdad? Una clase local no puede ser estática ni transitoria , pero se puede marcar como abstracta o final (solo OR, ya que el uso de estos dos modificadores provocará un conflicto). 4. Clases anónimas Ya hemos hablado anteriormente de clases anónimas y, como recordará, se pueden crear a partir de dos fuentes: interfaces y clases. Las razones para utilizar clases internas estáticas y no estáticas se utilizan porque a veces es mejor integrar clases pequeñas dentro de otras más grandes y mantenerlas juntas: de esta manera tendrán mayor cohesión y un propósito común. De hecho, el uso de clases anidadas aumenta la encapsulación del código. El motivo para elegir clases locales puede ser que una clase determinada se utilice exclusivamente dentro de un único método. En este caso, ¿es necesario distribuir el código por toda la aplicación? No. Pero al mismo tiempo agregaré que en mi práctica nunca he visto el uso de clases locales, porque la necesidad de ellos es muy controvertida. Bueno, la razón para usar clases anónimas puede ser que una implementación específica de una interfaz o clase abstracta será necesaria solo una vez, por lo que no es necesario crear una clase separada y completa con una implementación para esto. En cambio, de una manera sencilla, implementamos los métodos que necesitábamos a través de una clase anónima, usamos este objeto y nos olvidamos de él (bueno, el recolector de basura lo recordó). Este y este artículo te ayudarán a estudiar las clases internas con más detalle .
51. ¿Qué modificadores de acceso puede tener una clase?
Como recordamos, existen diferentes tipos de clases y a ellas se les aplican diferentes modificadores de acceso:- una clase externa puede tener el modificador de acceso público o no tener modificador (modificador predeterminado);
- la clase interna admite los 4 modificadores de acceso;
- La clase estática anidada admite todos los modificadores de acceso excepto protected , porque este modificador implica herencia, lo que contradice el miembro estático de la clase (los elementos estáticos no se heredan);
- una clase local sólo puede tener un modificador predeterminado (es decir, ningún modificador);
- clase anónima : si no hay una declaración de tipo de clase, entonces no hay ningún modificador de acceso.
GO TO FULL VERSION