Eu sei que Java não tem ponteiros, mas ouvi dizer que programas Java podem ser criados com ponteiros e que isso pode ser feito por poucos que são especialistas em java. É verdade?
Eu sei que Java não tem ponteiros, mas ouvi dizer que programas Java podem ser criados com ponteiros e que isso pode ser feito por poucos que são especialistas em java. É verdade?
Respostas:
Todos os objetos em Java são referências e você pode usá-los como ponteiros.
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;
Desreferenciando um nulo:
first.growl(); // ERROR, first is null.
third.growl(); // ERROR, third has not been initialized.
Problema de aliasing:
third = new Tiger();
first = third;
Células perdidas:
second = third; // Possible ERROR. The old value of second is lost.
Você pode tornar isso seguro garantindo primeiro que não há mais necessidade do valor antigo de segundo ou atribuindo a outro ponteiro o valor de segundo.
first = second;
second = third; //OK
Observe que atribuir a segundo um valor de outras maneiras (NULL, novo ...) é um erro potencial e pode resultar na perda do objeto para o qual ele aponta.
O sistema Java lançará uma exceção ( OutOfMemoryError
) quando você chamar new e o alocador não puder alocar a célula solicitada. Isso é muito raro e geralmente resulta de uma recursão descontrolada.
Observe que, do ponto de vista da linguagem, abandonar objetos para o coletor de lixo não é um erro. É apenas algo que o programador precisa estar ciente. A mesma variável pode apontar para objetos diferentes em momentos diferentes e valores antigos serão recuperados quando nenhum ponteiro fizer referência a eles. Mas se a lógica do programa requer a manutenção de pelo menos uma referência ao objeto, isso causará um erro.
Os novatos freqüentemente cometem o seguinte erro.
Tiger tony = new Tiger();
tony = third; // Error, the new object allocated above is reclaimed.
O que você provavelmente quis dizer foi:
Tiger tony = null;
tony = third; // OK.
Fundição imprópria:
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.
Ponteiros em 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
}
Ponteiros em 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
}
}
ATUALIZAÇÃO: conforme sugerido nos comentários, deve-se observar que C possui aritmética de ponteiros. No entanto, não temos isso em Java.
Java tem ponteiros. Sempre que você cria um objeto em Java, na verdade está criando um ponteiro para o objeto; esse ponteiro pode então ser definido para um objeto diferente ou para null
, e o objeto original ainda existirá (coleta de lixo pendente).
O que você não pode fazer em Java é aritmética de ponteiro. Você não pode desreferenciar um endereço de memória específico ou incrementar um ponteiro.
Se você realmente deseja obter um nível inferior, a única maneira de fazer isso é com a Java Native Interface ; e mesmo assim, a parte de baixo nível tem que ser feita em C ou C ++.
Como Java não tem tipos de dados de ponteiro, é impossível usar ponteiros em Java. Mesmo os poucos especialistas não serão capazes de usar ponteiros em java.
Veja também o último ponto em: The Java Language Environment
Existem ponteiros em Java, mas você não pode manipulá-los da maneira que faria em C ++ ou C. Quando você passa um objeto, está passando um ponteiro para esse objeto, mas não no mesmo sentido que em C ++. Esse objeto não pode ser referenciado. Se você definir seus valores usando seus acessadores nativos, ele mudará porque o Java conhece sua localização na memória por meio do ponteiro. Mas o ponteiro é imutável. Ao tentar definir o ponteiro para um novo local, em vez disso, você acaba com um novo objeto local com o mesmo nome do outro. O objeto original não foi alterado. Aqui está um breve programa para demonstrar a diferença.
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;
}
}
Isso pode ser executado em Ideone.com.
Java não tem ponteiros como o C, mas permite que você crie novos objetos no heap que são "referenciados" por variáveis. A falta de ponteiros impede que os programas Java façam referência a localizações de memória ilegalmente e também permite que a Coleta de Lixo seja realizada automaticamente pela Java Virtual Machine.
Você pode usar endereços e ponteiros usando a classe Unsafe. No entanto, como o nome sugere, esses métodos são INSEGUROS e geralmente uma má ideia. O uso incorreto pode resultar na morte aleatória de sua JVM (na verdade, o mesmo problema é o uso de ponteiros incorretamente em C / C ++)
Embora você possa estar acostumado a ponteiros e pense que precisa deles (porque não sabe codificar de outra maneira), você descobrirá que não sabe e ficará melhor com isso.
Tecnicamente, todos os objetos Java são ponteiros. Todos os tipos primitivos são valores. Não há como assumir o controle manual desses ponteiros. Java usa apenas passagem por referência internamente.
Não, realmente não.
Java não tem ponteiros. Se você realmente quisesse, poderia tentar emulá-los construindo em torno de algo como o reflexo, mas teria toda a complexidade dos indicadores sem nenhum dos benefícios .
Java não tem ponteiros porque não precisa deles. Que tipo de respostas você esperava com essa pergunta, ou seja, no fundo, você esperava que pudesse usá-las para algo ou foi apenas curiosidade?
Todos os objetos em java são passados para funções por cópia de referência, exceto primitivos.
Na verdade, isso significa que você está enviando uma cópia do ponteiro para o objeto original, em vez de uma cópia do próprio objeto.
Por favor, deixe um comentário se quiser um exemplo para entender isso.
swap
função em Java que irá trocar dois objetos.
Como já foi dito, a resposta curta é "Não".
Claro, você poderia escrever código JNI que brinca com ponteiros Java. Dependendo do que você está tentando realizar, talvez isso o levasse a algum lugar, talvez não.
Você sempre pode simular pontos criando uma matriz e trabalhando com índices na matriz. Novamente, dependendo do que você está tentando realizar, isso pode ou não ser útil.
do livro Decompiling Android de Godfrey Nolan
A segurança determina que os ponteiros não sejam usados em Java, de forma que os hackers não possam sair de um aplicativo e entrar no sistema operacional. Sem ponteiros significa que alguma outra coisa ---- neste caso, a JVM ---- deve cuidar da alocação e liberação de memória. Vazamentos de memória também deveriam se tornar uma coisa do passado, ou assim diz a teoria. Alguns aplicativos escritos em C e C ++ são notórios por vazar memória como uma peneira porque os programadores não prestam atenção em liberar memória indesejada no momento apropriado - não que alguém lendo isso seja culpado de tal pecado. A coleta de lixo também deve tornar os programadores mais produtivos, com menos tempo gasto na depuração de problemas de memória.
você pode ter ponteiros para literais também. Você tem que implementá-los sozinho. É bastante básico para especialistas;). Use um array de int / object / long / byte e voila, você tem o básico para implementar ponteiros. Agora, qualquer valor int pode ser um ponteiro para esse array int []. Você pode incrementar o ponteiro, pode decrementar o ponteiro, pode multiplicar o ponteiro. Você realmente tem aritmética de ponteiro! Essa é a única maneira de implementar 1000 classes de atributos int e ter um método genérico que se aplica a todos os atributos. Você também pode usar uma matriz de bytes [] em vez de um int []
No entanto, eu gostaria que o Java deixasse você passar valores literais por referência. Algo ao longo das linhas
//(* telling you it is a pointer)
public void myMethod(int* intValue);
Todos os objetos java são apontadores porque uma variável que contém o endereço é chamada de apontador e o objeto contém o endereço.so objeto é uma variável do ponteiro.