Sé que Java no tiene punteros, pero escuché que los programas Java se pueden crear con punteros y que esto lo pueden hacer unos pocos expertos en Java. ¿Es verdad?
Sé que Java no tiene punteros, pero escuché que los programas Java se pueden crear con punteros y que esto lo pueden hacer unos pocos expertos en Java. ¿Es verdad?
Respuestas:
Todos los objetos en Java son referencias y puede usarlos como punteros.
abstract class Animal
{...
}
class Lion extends Animal
{...
}
class Tiger extends Animal
{
public Tiger() {...}
public void growl(){...}
}
Tiger first = null;
Tiger second = new Tiger();
Tiger third;
Desreferenciar un nulo:
first.growl(); // ERROR, first is null.
third.growl(); // ERROR, third has not been initialized.
Problema de aliasing:
third = new Tiger();
first = third;
Perdiendo células:
second = third; // Possible ERROR. The old value of second is lost.
Puede hacer que esto sea seguro asegurándose primero de que no hay más necesidad del valor anterior de segundo o asignando a otro puntero el valor de segundo.
first = second;
second = third; //OK
Tenga en cuenta que dar a second un valor de otras formas (NULL, new ...) es un error potencial y puede resultar en la pérdida del objeto al que apunta.
El sistema Java generará una excepción ( OutOfMemoryError
) cuando llame a new y el asignador no pueda asignar la celda solicitada. Esto es muy raro y generalmente es el resultado de una recursión de fuga.
Tenga en cuenta que, desde el punto de vista del lenguaje, abandonar objetos al recolector de basura no son errores en absoluto. Es algo de lo que el programador debe estar consciente. La misma variable puede apuntar a diferentes objetos en diferentes momentos y los valores antiguos se recuperarán cuando ningún puntero haga referencia a ellos. Pero si la lógica del programa requiere mantener al menos una referencia al objeto, provocará un error.
Los novatos suelen cometer el siguiente error.
Tiger tony = new Tiger();
tony = third; // Error, the new object allocated above is reclaimed.
Lo que probablemente quisiste decir fue:
Tiger tony = null;
tony = third; // OK.
Casting inadecuado:
Lion leo = new Lion();
Tiger tony = (Tiger)leo; // Always illegal and caught by compiler.
Animal whatever = new Lion(); // Legal.
Tiger tony = (Tiger)whatever; // Illegal, just as in previous example.
Lion leo = (Lion)whatever; // Legal, object whatever really is a Lion.
Punteros en C:
void main() {
int* x; // Allocate the pointers x and y
int* y; // (but not the pointees)
x = malloc(sizeof(int)); // Allocate an int pointee,
// and set x to point to it
*x = 42; // Dereference x to store 42 in its pointee
*y = 13; // CRASH -- y does not have a pointee yet
y = x; // Pointer assignment sets y to point to x's pointee
*y = 13; // Dereference y to store 13 in its (shared) pointee
}
Punteros en Java:
class IntObj {
public int value;
}
public class Binky() {
public static void main(String[] args) {
IntObj x; // Allocate the pointers x and y
IntObj y; // (but not the IntObj pointees)
x = new IntObj(); // Allocate an IntObj pointee
// and set x to point to it
x.value = 42; // Dereference x to store 42 in its pointee
y.value = 13; // CRASH -- y does not have a pointee yet
y = x; // Pointer assignment sets y to point to x's pointee
y.value = 13; // Deference y to store 13 in its (shared) pointee
}
}
ACTUALIZACIÓN: como se sugiere en los comentarios, se debe tener en cuenta que C tiene aritmética de puntero. Sin embargo, no tenemos eso en Java.
Java tiene punteros. Cada vez que crea un objeto en Java, en realidad está creando un puntero al objeto; este puntero podría establecerse en un objeto diferente o en null
, y el objeto original seguirá existiendo (recolección de basura pendiente).
Lo que no puedes hacer en Java es aritmética de punteros. No puede eliminar la referencia a una dirección de memoria específica o incrementar un puntero.
Si realmente desea obtener un nivel bajo, la única forma de hacerlo es con la interfaz nativa de Java ; e incluso entonces, la parte de bajo nivel debe hacerse en C o C ++.
Como Java no tiene tipos de datos de puntero, es imposible utilizar punteros en Java. Incluso los pocos expertos no podrán usar punteros en java.
Consulte también el último punto en: El entorno del lenguaje Java
Hay punteros en Java, pero no puede manipularlos de la forma en que puede hacerlo en C ++ o C. Cuando pasa un objeto, está pasando un puntero a ese objeto, pero no en el mismo sentido que en C ++. Ese objeto no se puede desreferenciar. Si establece sus valores utilizando sus accesos nativos, cambiará porque Java conoce su ubicación de memoria a través del puntero. Pero el puntero es inmutable. Cuando intenta establecer el puntero en una nueva ubicación, en su lugar termina con un nuevo objeto local con el mismo nombre que el otro. El objeto original no se modifica. Aquí hay un breve programa para demostrar la diferencia.
import java.util.*;
import java.lang.*;
import java.io.*;
class Ideone {
public static void main(String[] args) throws java.lang.Exception {
System.out.println("Expected # = 0 1 2 2 1");
Cat c = new Cat();
c.setClaws(0);
System.out.println("Initial value is " + c.getClaws());
// prints 0 obviously
clawsAreOne(c);
System.out.println("Accessor changes value to " + c.getClaws());
// prints 1 because the value 'referenced' by the 'pointer' is changed using an accessor.
makeNewCat(c);
System.out.println("Final value is " + c.getClaws());
// prints 1 because the pointer is not changed to 'kitten'; that would be a reference pass.
}
public static void clawsAreOne(Cat kitty) {
kitty.setClaws(1);
}
public static void makeNewCat(Cat kitty) {
Cat kitten = new Cat();
kitten.setClaws(2);
kitty = kitten;
System.out.println("Value in makeNewCat scope of kitten " + kitten.getClaws());
//Prints 2. the value pointed to by 'kitten' is 2
System.out.println("Value in makeNewcat scope of kitty " + kitty.getClaws());
//Prints 2. The local copy is being used within the scope of this method.
}
}
class Cat {
private int claws;
public void setClaws(int i) {
claws = i;
}
public int getClaws() {
return claws;
}
}
Esto se puede ejecutar en Ideone.com.
Java no tiene punteros como C, pero te permite crear nuevos objetos en el montón a los que "hacen referencia" las variables. La falta de indicadores es para evitar que los programas Java hagan referencia a ubicaciones de memoria ilegalmente y también permite que la máquina virtual Java lleve a cabo la recolección de basura automáticamente.
Puede utilizar direcciones y punteros con la clase Inseguro. Sin embargo, como sugiere el nombre, estos métodos NO SON SEGUROS y generalmente son una mala idea. El uso incorrecto puede provocar que su JVM muera aleatoriamente (en realidad, el mismo problema es el uso incorrecto de punteros en C / C ++)
Si bien puede estar acostumbrado a los punteros y pensar que los necesita (porque no sabe cómo codificar de otra manera), descubrirá que no es así y será mejor para ello.
Técnicamente, todos los objetos de Java son punteros. Sin embargo, todos los tipos primitivos son valores. No hay forma de tomar el control manual de esos punteros. Java solo usa internamente paso por referencia.
No, realmente no.
Java no tiene punteros. Si realmente lo quisiera, podría intentar emularlos construyendo alrededor de algo como la reflexión, pero tendría toda la complejidad de los punteros sin ninguno de los beneficios .
Java no tiene punteros porque no los necesita. ¿Qué tipo de respuestas esperabas de esta pregunta, es decir, en el fondo, ¿esperabas poder usarlas para algo o era solo curiosidad?
Todos los objetos en java se pasan a funciones por copia de referencia excepto primitivas.
En efecto, esto significa que está enviando una copia del puntero al objeto original en lugar de una copia del objeto en sí.
Deje un comentario si desea un ejemplo para entender esto.
swap
función en Java que intercambie dos objetos.
Como han dicho otros, la respuesta corta es "No".
Claro, podría escribir código JNI que juegue con punteros Java. Dependiendo de lo que esté tratando de lograr, tal vez eso lo lleve a algún lugar y tal vez no.
Siempre puede simular puntos creando una matriz y trabajando con índices en la matriz. Nuevamente, dependiendo de lo que intente lograr, eso podría ser útil o no.
del libro llamado Decompiling Android de Godfrey Nolan
La seguridad dicta que los punteros no se utilizan en Java para que los piratas informáticos no puedan salir de una aplicación y entrar en el sistema operativo. Sin punteros significa que algo más, en este caso, la JVM, tiene que encargarse de la asignación y liberación de memoria. Las pérdidas de memoria también deberían convertirse en una cosa del pasado, o eso dice la teoría. Algunas aplicaciones escritas en C y C ++ son conocidas por perder memoria como un colador porque los programadores no prestan atención a liberar memoria no deseada en el momento apropiado, no es que cualquiera que lea esto sea culpable de tal pecado. La recolección de basura también debería hacer que los programadores sean más productivos, con menos tiempo dedicado a depurar problemas de memoria.
también puede tener punteros para literales. Tienes que implementarlos tú mismo. Es bastante básico para los expertos;). Use una matriz de int / object / long / byte y listo, tiene los conceptos básicos para implementar punteros. Ahora cualquier valor int puede ser un puntero a esa matriz int []. Puede incrementar el puntero, puede disminuir el puntero, puede multiplicar el puntero. ¡De hecho, tienes aritmética de punteros! Esa es la única forma de implementar 1000 clases de atributos int y tener un método genérico que se aplique a todos los atributos. También puede utilizar una matriz de bytes [] en lugar de un int []
Sin embargo, me gustaría que Java le permitiera pasar valores literales por referencia. Algo a lo largo de las líneas
//(* telling you it is a pointer)
public void myMethod(int* intValue);
Todos los objetos de Java son punteros porque una variable que contiene la dirección se llama puntero y el objeto retiene la dirección, por lo que el objeto es una variable de puntero.