|
![]() |
Clase Object |
Anterior | Siguiente |
La clase Object, como ya se ha indicado
anteriormente, es la clase raíz de todo el árbol de la jerarquía de clases Java, y
proporciona un cierto número de métodos de utilidad general que pueden utilizar todos
los objetos. La lista completa se puede ver en la documentación del API de Java, aquí
solamente se tratarán algunos de ellos; por ejemplo, Object proporciona:
public boolean equals( Object obj ); Todas las clases que se definan en Java heredarán el método equals(), que se puede utilizar para comparar dos objetos. Esta comparación no es la misma que proporciona el operador ==, que solamente compara si dos referencias a objetos apuntan al mismo objeto. El método equals() se utiliza para saber si dos objetos separados son del mismo tipo y contienen los mismos datos. El método devuelve true si los objetos son iguales y false en caso contrario. El sistema ya sabe de antemano cómo aplicar el método a todas las clases estándar y a todos los objetos de los que el compilador tiene conocimiento. Por ejemplo, se puede usar directamente para saber si dos objetos String son iguales. Las subclases pueden sobreescribir el método equals() para realizar la adecuada comparación entre dos objetos de un tipo que haya sido definido por el programador. En la aplicación de ejemplo siguiente, java511.java, se sobreescribe el método para comparar dos objetos de la nueva clase que crea la aplicación. Hay que observar que en la lista de argumentos del método equals() hay que pasarle un argumento de tipo Object. Si se define un método con un argumento de tipo diferente, se estará sobrecargando el método, no sobreescribiéndolo. En el ejemplo, una vez que se ejecuta, es necesario hacer un moldeo del argumento al tipo de la clase antes de intentar realizar la comparación. Se utiliza el operador instanceof para confirmar que el objeto es del tipo correcto. Uno de los objetos proporcionados para comprobar su equivalencia es de tipo erróneo (String) y el método sobreescrito equals() indicará que no es un objeto equivalente. class java511 { int miDato; // Constructor parametrizado java511( int dato ) { miDato = dato; } public static void main(String args[] ) { // Se instancian los objetos que se van a testear java511 obj1 = new java511( 2 ); java511 obj2 = new java511( 2 ); java511 obj3 = new java511( 3 ); String obj4 = "Un objeto String"; // Se realizan las comprobaciones y se presenta por pantalla // el resultado de cada una de ellas System.out.println( "obj1 equals obj1: " + obj1.equals( obj1 ) ); System.out.println( "obj1 equals obj2: " + obj1.equals( obj2 ) ); System.out.println( "obj1 equals obj3: " + obj1.equals( obj3 ) ); System.out.println( "obj1 equals obj4: " + obj1.equals( obj4 ) ); } // Se sobreescribe el metodo equals() public boolean equals( Object arg ) { // Se comprueba que el argumento es del tipo adecuado y // que no es nulo. Si lo anterior se cumple se realiza // la comprobacion de equivalencia de los datos. // Observese que se ha empleado el operador instanceof if( (arg != null) && (arg instanceof java511) ) { // Hacemos un moldeado del Object general a tipo java511 java511 temp = (java511)arg; // Se realiza la comparacion y se devuelve el resultado return( this.miDato == temp.miDato ); } else { // No es del tipo esperado return( false ); } } } public final native Class getClass(); En Java existe la clase Class, que se define de la forma (la declaración no está completa, consultar el API de Java para ello): public final class java.lang.Class extends java.lang.Object { // Métodos public static Class forName(String className); public ClassLoader getClassLoader(); public Class[] getClasses(); public Class getComponentType(); public Constructor getConstructor(Class[] parameterTypes); public Constructor[] getConstructors(); public Class[] getDeclaredClasses(); public Constructor[] getDeclaredConstructors(); public Field getDeclaredField(String name); public Field[] getDeclaredFields(); public Method getDeclaredMethod(String name, Class[] parTypes); public Method[] getDeclaredMethods(); public Class getDeclaringClass(); public Field getField(String name); public Field[] getFields(); public Class[] getInterfaces(); public Method getMethod(String name, Class[] parameterTypes); public Method[] getMethods(); public int getModifiers(); public String getName(); public URL getResource(String name); public InputStream getResourceAsStream(String name); public Object[] getSigners(); public Class getSuperclass(); public boolean isArray(); public boolean isAssignableFrom(Class cls); public boolean isInstance(Object obj); public boolean isInterface(); public boolean isPrimitive(); public Object newInstance(); public String toString(); // Overrides Object.toString() } Instancias de la clase Class representan las clases e interfaces que está ejecutando la aplicación Java. No hay un constructor para la clase Class, sus objetos son construidos automáticamente por la Máquina Virtual Java (JVM) cuando las clases son cargadas, o por llamadas al método defineClass() del cargados de clases. Es una clase importante porque se le pueden realizar peticiones de información sobre objetos, como cuál es su nombre o cómo se llama su superclase. El método getClass() de la clase Object se puede utilizar para determinar la clase de un objeto. Es decir, devuelve un objeto de tipo Class, que contiene información importante sobre el objeto que crea la clase. Una vez determinada la clase del objeto, se pueden utilizar los métodos de la clase Class para obtener información acerca del objeto. Además, habiendo determinado la clase del objeto, el método newInstance() de la clase Class puede invocarse para instanciar otro objeto del mismo tipo. El resultado es que el operador new será utilizado con un constructor de una clase conocida. Hay que hacer notar que la última afirmación del párrafo anterior es una situación que el compilador no conoce en tiempo de compilación, es decir, no sabe el tipo del objeto que va a ser instanciado. Por lo tanto, si se necesita referenciar al nuevo objeto, es necesario declarar la variable de referencia del tipo genérico Object, aunque el objeto actual tomará todos los atributos de la subclase actual por la que será instanciado. Hay que hacer notar que el método getClass() es un método final y no puede ser sobreescrito. Devuelve un objeto de tipo Class que permite el uso de los métodos definidos en la clase Class sobre ese objeto. El siguiente programa, java512.java, ilustra alguna de estas características. Primero, instancia un objeto, mira la clase de ese objeto y utiliza alguno de los métodos de la clase Class para obtener y presentar información acerca del objeto. Luego, pregunta al usuario si quiere instanciar un nuevo objeto, instanciando un objeto de tipo String en un caso o, en el otro caso, se aplica el método getClass() a un objeto existente y utilizando el método newInstance() se instancia un nuevo objeto del mismo tipo. import java.io.*; class java512 { public static void main( String args[] ) { java512 obj1 = new java512(); // Se usa el metodo getClass() de la clase Object y dos // metodos de la clase Class para obtener y presentar // informacion acerca del objeto System.out.println( "Nombre de la clase de obj1: " + obj1.getClass().getName() ); System.out.println( "Nombre de la superclase de obj1: " + obj1.getClass().getSuperclass() ); // Ahora se instancia otro objeto basandose en la entrada // del usuario, de forma que el compilador no tiene forma // de conocer el tipo del objeto en tiempo de compilacion // Se declara una referencia a un objeto generico Object obj2 = null; // Se pide la entrada al usuario System.out.println( "Introduce un 0 o un 1" ); try { // Captura la entrada del usuario int dato = System.in.read(); // Si se ha introducido un 0 if( (char)dato == '0' ) // Se crea un objeto String obj2 = "Esto es un objeto String"; // Sino, se crea un nuevo objeto del mismo tipo // que el anterior else obj2 = obj1.getClass().newInstance(); } catch( Exception e ) { System.out.println( "Excepcion " + e ); } // Ahora se indican la clase y superclase del nuevo objeto System.out.println( "Nombre de la clase de obj2: " + obj2.getClass().getName() ); System.out.println( "Nombre de la superclase de obj2: " + obj2.getClass().getSuperclass()); } } public String toString(); La clase Object dispone de este método que puede usarse para convertir todos los objetos conocidos por el compilador a algún tipo de representación de cadena, que dependerá del objeto. Por ejemplo, el método toString() extrae el entero contenido en un objeto Integer. De forma similar, si se aplica el método toString() al objeto Thread, se puede obtener información importante acerca de los threads y presentarla como cadena. Este método también se puede sobreescribir, o redefinir, para convertir los objetos definidos por el programador a cadenas. El programa siguiente, java513.java, redefine el método toString() de una clase recién definida para que pueda utilizarse en la conversión de objetos de esta clase a cadenas. class java513 { // Se definen las variables de instancia para la clase String uno; String dos; String tres; // Constructor de la clase java513( String a,String b,String c ) { uno = a; dos = b; tres = c; } public static void main( String args[] ) { // Se instancia un objeto de la clase java513 obj = new java513( "Tutorial","de","Java" ); // Se presenta el objeto utilizando el metodo sobreescrito System.out.println( obj.toString() ); } // Sobreescritura del metodo toString() de la clase Object public String toString() { // Convierte un objeto a cadena y lo devuelve return( uno+" "+dos+" "+tres ); } } Hay otros métodos útiles en la clase Object que son, o serán, discutidos en otras secciones de este documento. Por ejemplo, el método protected void finalize(); que se tratará en el apartado de finalizadores. O también, los métodos que se utilizan en la programación de threads para hacer que varios threads se sincronicen, como son public final void wait(); public final native void wait( long timeout ); public final native void notify(); public final native void notifyAll(); que se tratarán cuando se hable del multithreading en Java. |
|