Hemos estado usando el concepto de "objeto" antes, pero no hemos discutido la forma específica en que los objetos se almacenan en la memoria. Esta discusión conducirá al importante concepto de "referencia de objeto".
referencia de objeto
Seguimos usando la clase Human definida anteriormente y tenemos una clase Test:
Copie el código de código de la siguiente manera:
prueba de clase pública
{
principal vacío estático público (String [] argumentos)
{
Humano aPersona = nuevo Humano(160);
}
}
claseHumano
{
/**
* constructor
*/
humano público (int h)
{
esta.altura = h;
}
/**
*accesor
*/
público int getHeight()
{
devolver esta altura;
}
/**
* mutador
*/
altura de crecimiento del vacío público (int h)
{
esta.altura = esta.altura + h;
}
altura interna privada;
}
Las clases se pueden llamar externamente para crear objetos, como el anterior en la clase Prueba:
Copie el código de código de la siguiente manera:
Humano aPersona = nuevo Humano(160);
Se crea un objeto de clase Persona de Humano.
Lo anterior es una declaración muy simple, pero tenemos muchos detalles en los que entrar:
1. Primero mira el lado derecho del signo igual. new abre espacio para objetos en la memoria. Específicamente, lo nuevo abre espacio para objetos en el montón de memoria. En este espacio se almacenan los datos y métodos del objeto.
2. Mira el lado izquierdo del signo igual. aPersona se refiere a un objeto Humano, lo que se denomina referencia de objeto. De hecho, una Persona no es el objeto en sí, sino que es similar a un puntero al objeto. aPerson existe en la pila en la memoria.
3. Cuando usamos el signo igual para asignar un valor, la dirección del objeto creado en el montón por nuevo a la derecha se asigna a la referencia del objeto.
La memoria aquí se refiere al espacio de memoria del proceso Java virtualizado por la JVM (Máquina virtual Java). Para conocer los conceptos de montón y pila en la memoria, consulte Linux del programa al proceso.
La pila se puede leer más rápido que el montón, pero los datos almacenados en la pila están limitados por el rango válido. En lenguaje C, cuando finaliza una llamada a una función, el marco de pila correspondiente se elimina y los parámetros y variables automáticas almacenados en el marco de pila desaparecen. La pila de Java también está sujeta a la misma restricción. Cuando finaliza una llamada a un método, los datos almacenados en la pila por el método se borrarán. En Java, todos los objetos (ordinarios) se almacenan en el montón. Por lo tanto, el significado completo de la nueva palabra clave es crear un objeto en el montón.
Los objetos de tipos primitivos, como int y double, se almacenan en la pila. Cuando declaramos un tipo básico, no hay necesidad de nuevo. Una vez declarado, Java almacena tipos primitivos de datos directamente en la pila. Por lo tanto, el nombre de la variable de un tipo básico representa los datos en sí, no una referencia.
La relación entre referencias y objetos es como una cometa y una persona. Cuando miramos al cielo (escrito en el programa), lo que vemos es una cometa (referencia), pero lo que corresponde a la cometa es una persona (objeto):
Separación de referencias y objetos; las referencias apuntan a objetos;
Aunque las referencias y los objetos están separados, todo nuestro acceso a los objetos debe pasar por la "puerta" de las referencias, como acceder a los métodos de los objetos a través de reference.method(). En Java, no podemos omitir referencias y tocar objetos directamente. Para otro ejemplo, si el miembro de datos del objeto a es un objeto b ordinario, el miembro de datos de a guarda una referencia al objeto b (si es una variable de tipo básico, entonces el miembro de datos de a guarda la variable de tipo básico en sí) .
En Java, las referencias desempeñan el papel de punteros, pero no podemos modificar directamente el valor del puntero, como agregar 1 al valor del puntero como en el lenguaje C. Solo podemos realizar operaciones sobre objetos a través de referencias. Este diseño evita muchos errores que pueden provocar los punteros.
asignación de referencia
Cuando asignamos una referencia a otra referencia, en realidad estamos copiando la dirección del objeto. Ambas referencias apuntarán al mismo objeto. Por ejemplo, dummyPerson=aPerson dará como resultado:
Un objeto puede tener múltiples referencias (una persona puede volar varias cometas). Cuando un programa modifica un objeto a través de una referencia, la modificación es visible a través de otras referencias. Podemos usar la siguiente clase de prueba para probar el efecto real:
Copie el código de código de la siguiente manera:
prueba de clase pública
{
principal vacío estático público (String [] argumentos)
{
Humano aPersona = nuevo Humano(160);
Persona ficticia humana = una Persona;
System.out.println(dummyPerson.getHeight());
unaPersona.growHeight(20);
System.out.println(dummyPerson.getHeight());
}
}
Nuestras modificaciones a aPerson afectarán a dummyPerson. Estas dos referencias en realidad apuntan al mismo objeto.
Por lo tanto, asignar una referencia a otra referencia no copia el objeto en sí. Debemos encontrar otros mecanismos para copiar objetos.
Recolección de basura
Cuando finaliza la llamada al método, las variables de tipo primitivo y de referencia se borran. Dado que el objeto vive en el montón, la memoria ocupada por el objeto no se borrará cuando finalice la llamada al método. El espacio del proceso puede llenarse rápidamente con objetos que se están creando. Java tiene un mecanismo de recolección de basura incorporado para borrar objetos que ya no se utilizan para recuperar espacio de memoria.
El principio básico de la recolección de basura es que cuando hay una referencia que apunta a un objeto, el objeto no se reciclará; cuando no hay ninguna referencia que apunte a un objeto, el objeto se borra; Se recupera el espacio que ocupa.
La figura anterior supone el estado de la memoria en la JVM en un momento determinado. El Objeto Humano tiene tres referencias: una Persona y una Persona ficticia de la pila, y el presidente, un miembro de datos de otro objeto. El Objeto Club no tiene referencia. Si se inicia la recolección de basura en este momento, el Objeto Club se vaciará y la referencia del Objeto Humano (presidente) del Objeto Club también se eliminará.
La recolección de basura es un mecanismo importante en Java que afecta directamente la eficiencia operativa de Java. Entraré en los detalles de eso más tarde.
paso de parámetros
Cuando separamos los conceptos de referencias y objetos, el mecanismo de paso de parámetros de los métodos Java es realmente muy claro: el paso de parámetros de Java se realiza por valor. Es decir, cuando pasamos un parámetro, el método obtendrá una copia del parámetro.
De hecho, uno de los parámetros que pasamos es una variable de tipo básico y el otro es una referencia al objeto.
El paso por valor para variables de tipo primitivo significa que la variable misma se copia y se pasa al método Java. Las modificaciones de variables mediante métodos Java no afectarán a las variables originales.
Pasar por valor significa que la dirección del objeto se copia y se pasa al método Java. El acceso al método Java basado en esta referencia afectará al objeto.
Hay otra situación que vale la pena mencionar aquí: usamos new dentro del método para crear un objeto y devolver una referencia al objeto. Si la devolución se recibe mediante una referencia, dado que la referencia del objeto no es 0, el objeto aún existe y no se recolectará como basura.
Resumir
nuevo
referencia, objeto
Condiciones para la recogida de basura.
Parámetros: pasados por valor