Java: el fundamento de la clase Object no se ha declarado abstracto
specifications (9)
¿Cómo es Object más ofensivo que nulo?
Es un buen marcador de lugar (igual que nulo).
Además, no creo que sea un buen diseño hacer que un objeto sea abstracto sin un método abstracto que deba incluirlo.
No estoy diciendo que nulo sea lo mejor desde que se cortó el pan: leí un artículo el otro día en el "Inventor" que analiza el costo / valor de tener el concepto de nulo ... (Ni siquiera pensé que era nulo ¡Inventable! Supongo que alguien en algún lugar podría decir que inventó cero ...) el hecho de que sea capaz de crear una instancia de Object no es peor que ser capaz de pasar null.
¿Por qué la clase java.lang.Object
no fue declarada abstracta?
Seguramente para que un Objeto sea útil necesita un estado o comportamiento agregado, una clase de Objeto es una abstracción, y como tal debería haber sido declarada abstracta ... ¿por qué eligieron no hacerlo?
¿El Objeto especifica los métodos que las clases que lo extienden deben implementar para que sean útiles? No, y por lo tanto no tiene por qué ser abstracto.
El concepto de una clase que es abstracta tiene un significado bien definido que no se aplica a Objeto.
Ande, creo que te estás acercando a esto, sin pretenderlo, con un grado innecesario de abstracción. Creo que este nivel de abstracción innecesario (IMHO) es lo que está causando el "problema" aquí. Quizás esté enfocando esto desde un enfoque matemático teórico, donde muchos de nosotros lo estamos abordando desde un enfoque de "programador que intenta resolver problemas". Creo que esta diferencia en el enfoque está causando los desacuerdos.
Cuando los programadores observan los aspectos prácticos y cómo implementar realmente algo, hay un número de veces en que necesitas un Objeto totalmente arbitrario cuya instancia real es totalmente irrelevante. Simplemente no puede ser nulo. El ejemplo que le di en un comentario a otra publicación es la implementación de *Set
( *
== Hash
o Concurrent
o tipo de elección), que generalmente se realiza utilizando un *Map
respaldo *Map
y usando las teclas de Map
como el Conjunto. Con frecuencia, no puede utilizar null
como valor de Map
, por lo que lo que se suele hacer es usar una instancia de Object
estático como valor, que se ignorará y nunca se usará. Sin embargo, se necesita algún marcador de posición que no sea nulo.
Otro uso común es con la palabra clave synchronized
donde se necesita algún Object
para sincronizar, y desea asegurarse de que su elemento de sincronización sea totalmente privado para evitar el interbloqueo en el que las diferentes clases se sincronizan involuntariamente en el mismo bloqueo. Un lenguaje muy común es asignar un private final Object
para usar en una clase como el bloqueo. Para ser justos, a partir de Java 5 y java.util.concurrent.locks.Lock
y las adiciones relacionadas, este idioma es mucho menos aplicable.
Históricamente, ha sido bastante útil en Java tener Object
ser instanciable. Podría hacer una buena observación de que con pequeños cambios en el diseño o con pequeños cambios en la API, esto ya no sería necesario. Probablemente tienes razón en esto.
Y sí, la API podría haber proporcionado una clase de marcador de posición que amplía el Object
sin agregar nada en absoluto, para usarlo como marcador de posición para los fines descritos anteriormente. Pero, si está extendiendo el Object
pero sin agregar nada, ¿cuál es el valor en la clase aparte de permitir que el Object
sea abstracto? Matemáticamente, en teoría, tal vez uno podría encontrar un valor, pero de manera pragmática, ¿qué valor agregaría para hacer esto?
Hay veces en la programación donde necesita un objeto, algún objeto, cualquier objeto concreto que no sea nulo, algo que pueda comparar a través de ==
y / o .equals()
, pero simplemente no necesita ninguna otra característica para esto. objeto. Solo existe para servir como un identificador único y, de lo contrario, no hace absolutamente nada. Object
satisface perfectamente este papel y (IMHO) muy limpio.
Supongo que esto es parte de la razón por la que Object
no se declaró abstracto: es directamente útil para que no lo sea.
Como siempre, Guava viene a ayudar: con http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Optional.html Cosas aquí se pueden usar para eliminar nulos / instancias de objetos para "un marcador de posición no-nulo" del código.
Aquí hay preguntas completamente separadas:
- ¿Por qué no hicieron abstracto al objeto?
- ¿Cuánto desastre se produce después si deciden hacerlo abstracto en una versión futura?
No estoy seguro de que esta sea la razón, pero permite (o permite, ya que ahora hay mejores formas de hacerlo) que un Objeto se use como un bloqueo:
Object lock = new Object();
....
synchronized(lock)
{
}
Nunca se sabe cuándo es posible que desee utilizar un Objeto simple como un marcador de posición. Piense que es como tener un cero en un sistema numérico (y nulo no funciona para esto, ya que nulo representa la ausencia de datos).
Puede instanciar Object
para bloqueos de sincronización:
Object lock = new Object();
void someMethod() {
//safe stuff
synchronized(lock) {
//some code avoiding race condition
}
}
void someOtherMethod() {
//safe code
synchronized(lock) {
//some other stuff avoiding race condition
}
}
Un Object
es útil incluso si no tiene ningún estado o comportamiento específico.
Un ejemplo sería su uso como un guardián genérico que se usa para la sincronización:
public class Example {
private final Object o = new Object();
public void doSomething() {
synchronized (o) {
// do possibly dangerous stuff
}
}
}
Si bien esta clase es un poco simple en su implementación (no es evidente aquí por qué es útil tener un objeto explícito, podría declarar que el método está synchronized
), hay varios casos en que esto es realmente útil.
Debe haber una razón para hacer un resumen de clase. Una es evitar que los clientes ejemplifiquen la clase y obligarlos a usar solo subclases (por cualquier motivo). Otra es si desea usarlo como una interfaz proporcionando métodos abstractos, qué subclases deben implementar. Probablemente, los diseñadores de Java no vieron tales razones, por lo que java.lang.Object
sigue siendo concreto.