Ponteiro em Java

44 respostas
rodrigo.achilles

Olá pessoal,

gostaria de implementar uma estrutura com ponteiro em Java:

struct exe {
         int numero;
         struct *exe teste1;
         struct *exe teste2;
}

+/- assim…
alguém tem idéia para implementar esse tipo de ponteiro.

Obrigado

44 Respostas

fmeyer

AAAAAAAAAAAAAAAAHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
MULEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEQUE …

Java nao trabalha explicitamente com ponteiros …

oque voce pode fazer é criar uma classe com esses atributos … e ao inves de ponteiros voce REFERENCIA uma classe ao seu objeto.

Ps. Scottys0 com arrepios lembrando de alocação de memoria em C++

rodrigo.achilles

Ah, saquei…

É lógico, que ridículo, valeu mesmo scottys0. Que burro eu sou.

É simples assim! :smiley:

PS: Desculpa ter te lembrado esses tempos difíceis. :lol:

LuizAvila

rodrigo.achilles:
Ah, saquei…

É lógico, que ridículo, valeu mesmo scottys0. Que burro eu sou.

É simples assim! :smiley:

PS: Desculpa ter te lembrado esses tempos difíceis. :lol:

ahuuuuummmmmmm

Repita este mantra:

Java não é C++; Java não é C++; Java não é C++; Java não é C++;

ahuuuuummmmmmm

Eleve seu espírito, tire todas as impurezas de acesso direto a memória

ahuuuuummmmmmm

fmeyer

LuizAvila:
rodrigo.achilles:
Ah, saquei…

É lógico, que ridículo, valeu mesmo scottys0. Que burro eu sou.

É simples assim! :smiley:

PS: Desculpa ter te lembrado esses tempos difíceis. :lol:

ahuuuuummmmmmm

Repita este mantra:

Java não é C++; Java não é C++; Java não é C++; Java não é C++;

ahuuuuummmmmmm

Eleve seu espírito, tire todas as impurezas de acesso direto a memória

ahuuuuummmmmmm

A nao fala mau de C++ pq … tem muita coisa feito nele q funciona bem pra caramba …

O negocio é nao misturar as coisas …

uma das coisas que os caras amam fazer em provas de certificação java eh confundir o cara com C++, pelo menos é assim com SCJP … isso por que o objetivo do teste é ver se voce esta preparado para “as situações do mundo real” … então se o Eclipse/Netbeans/IntelliJ ou outra IDE tentar fazer voce digitar codigos em C++ … voce grita :

" EU RENUNCIO EM NOME DE JESUS … "

saoj
public class Exe {
    int numero;
    Exe teste1;
    Exe teste2;
}

Java tem ponteiro sim, só que aqui o nome é referencia. Vc só não tem acesso direto ao endereço de memória que ele representa, e por isso vc não pode manipular esse endereço.

A sun pode, através da class sun.misc.Unsafe.

Luca

Olá

Sérgio, sempre que vejo alguém dizer que Java tem ponteiro eu me lembro do tempo em que programava em Fortran. Naquela época a gente fazia na mão todo o endereçamento da memória. A gente alocava um array de uma dimensão com toda a memória livre da máquina e ficava movendo da memória para o disco e vice-versa. Fortran não tinha ponteiros mas a gente criava os ponteiros de endereçamento indireto e fazia aritmética com estes ponteiros.

Muitos anos depois inventaram o C e então pudemos usar os ponteiros com suporte dentro da linguagem. É óbvio que se a gente podia acessar uma determinada posição da memória então se podia acessar a tal posição acrescida de uma variável. Ou seja, a linguagem ter ponteiro significa que ela tem suporte a aritmética de ponteiro.

Para mim (e para todos os livros básicos que já li de Java), nossa linguagem favorita não tem suporte a ponteiros. O que a API faz lá dentro de modo nativo ou o fato de passar referências de forma alguma significa que Java tem ponteiros.

Não é a primeira vez aqui no GUJ que sou obrigado a me manifestar deste modo. Java não tem ponteiros e esta é uma das principais vantagens do Java.

Mas se você conseguir, me mostre um exemplo de uso de ponteiros em Java sem ser do modo que eu falei acima que fazia com Fortran. Mostre suporte da linguagem a aritmética com ponteiros.

[]s
Luca

saoj

Luca:
Mas se você conseguir, me mostre um exemplo de uso de ponteiros em Java sem ser do modo que eu falei acima que fazia com Fortran. Mostre suporte da linguagem a aritmética com ponteiros.

Não dá para fazer aritimética com ponteiros, nem para perguntar qual é o endereço físico de um ponteiro em Java. Foi o que eu falei.

Estou usando a palavra ponteiro como sinônimo de referencia. Talvez isso não seja legal, pois o cara confunde com os ponteiros do C. Deve ser por isso que o nome em Java é referência.

Posso estar errado. Estou apenas levantando a bola para discussão, mas penso que em Java há ponteiros, só que eles são totalmente protegidos do programador. Não temos acesso a eles.

Mas eles estão lá. Existem! Tanto existem que existe uma classe sun.misc.Unsafe que te permite acessar o endereço físico de uma referencia em Java e fazer artimética com ela. Acredite se quiser. Mas só os pacotes do core da linguagem podem fazer uso dessa classe. Ela tem funções que te retornam o endereço físico de memória de um objeto, acredite se quiser!

[color=red]OBS: O “acredite se quiser” aqui refere-se aquela série famosa da televisão onde o apresentador mostrava casos e situações bizarras e no final terminava com a frase: “Acredite se quiser!”. Ou seja, é apenas para enfatizar que a coisa é estranha mesmo![/color]

fmeyer

Essa bagunca ai em baixo é ponteiro…

int *p;  
int **r;      
int ***z;
c = **z + p;

… não sei , mas não consigo abstrair o conceito de ponteiro em java … pois eu ainda não vi uma referencia que aponte para outra referencia e assim sucessivamente. Se existir … alguem fale .

:slight_smile:

saoj

Não sei se é a mesma coisa, mas Java tem lista encadeada não tem ??? (LinkedList).

public class Node {
    private Object value;
    private Node next;
}

Na verdade aí vc tem um objeto que aponta para outro que contém uma referencia para outro objeto do mesmo tipo, formando uma cadeia. Acho que não equivale ao que vc falou. :roll:

Luca

Olá

Fortran tem arrays e tem índices dos arrays. Então quando se compila o fonte a linguagem gera uma aritmética em cima dos endereços dos índices porque assembler não tem arrays, somente tem aritmética direto sobre as posições de memória.

Estou fazendo esta comparação com uma linguagem que existe há mais de 40 anos para você ver que o que a linguagem de alto nível tem lá dentro para converter para linguagem de máquina não é uma facilidade da linguagem disponível ao programador.

Eu não tenho a menor idéia sobre como Java acessa as coisas nativas do sistema operacional porque não estão disponíveis para mim. E igualmente sigo afirmando que Java não disponibiliza ponteiros para uso do programador.

<editado>Editei para falar ao contrário: linguagem de máquina não tem estruturas de dados como arrays ou outros tipos (classes, struts, etc.), tem somente ponteiros. É assim que a gente programa em assembler.</editado>

[]s
Luca

fmeyer

saoj:
Não sei se é a mesma coisa, mas Java tem lista encadeada não tem ??? (LinkedList).

public class Node {
    private Object value;
    private Node next;
}

Na verdade aí vc tem um objeto que aponta para outro que contém uma referencia para outro objeto do mesmo tipo, formando uma cadeia. Acho que não equivale ao que vc falou. :roll:

Ai voce esta falando de estrutura de dados … em … c++

class Node {
       int valor;
       Node *next;
       ..  
};

estou falando de referencia pura … exemplo, uma variavel que contenha o endereco de outra sucessivamente ate acessar um valor na heap;

saoj

Sinistro !!! Acho que em Java não tem isso não, nem nas entranhas da VM, pois toda referencia aponta para um objeto, e todo objeto criado tem um header. Logo vc pode ter algo assim:

ponteiro -> header + ponteiro -> header + ponteiro, etc e tal…

ponteiro que aponta para outro ponteiro puro acho que não existe na especificação da VM mesmo…

fmeyer

Procurei ate cair cabelo … na especificação da linguagem e nao achei nada que falasse explicitamente de enderecamento e logica de acesso a heap… então …
http://java.sun.com/docs/books/jls/second_edition/html/jIX.fm.html

touche

Ironlynx

Estou usando a palavra ponteiro como sinônimo de referencia. Talvez isso não seja legal, pois o cara confunde com os ponteiros do C. Deve ser por isso que o nome em Java é referência.

Eu jah tinha postado isso aqui:
http://www.guj.com.br/posts/list/19722.java

Mas para ficar BEM claro a separação das coisas entre C,C++ e Java:
método em java(passagem por referência a objeto):

public static void troca(int[] ref,int x,int y){
      	int temp;
      	temp=ref[x];
      	ref[x]=ref[y];
      	ref[y]=temp;
     	                                        }//troca feita em Java

chamada ao método:
troca(ref,x,x+1);

função em C(passagem por referência por ponteiros):

void troca(int *x, int *y){
 	int temp = *x;
 	*x = *y;
 	*y = temp;
                          }//troca feita em C

chamada a função:
troca(&x,&y);

função em C++(passagem por referência):

void troca(int& x, int& y){
  int temp = x;
  x = y;
  y = temp;
                           }//troca feita em C++

chamada ao método:
troca(x,y);

int *x e int *y são os dois ponteiros que a função recebe como parâmetros.
O operador &(uppersign) é chamado de operador de endereços em C(que são passados aos ponteiros pela chamada da função).
Em C++,o operador & é o operador de referência(ele fica geralmente associado ao tipo da variável para se distinguir do operador de endereços de C) para as que forem passadas a função troca.
Ficou claro :?:

saoj

Dá uma olhada no código fonte do java.nio.DirectByteBuffer.

Tem acesso direto a memória, manipulação de ponteiros, etc.

Esse sun.misc.Unsafe foi feito pela Sun para a Sun. É para aqueles pouquíssimos casos críticos onde a VM precisa de acesso direto ao enderaçamento físico de memória RAM, como no java.nio.

Luca

Olá

Discordo, a JVM tem sempre que acessar a memória RAM e outras coisas lá no fundo. É ela que põe a mão na lama e faz isto de forma mais complexa que for necessário mas com intuito de facilitar a nossa vida.

Conforme já disse, a CPU não dispõe de instruções sofisticadas de estruturas de dados. Um array é mapeado na memória na raça do mesmo modo como eu fazia nos meus programas em Fortran. A JVM tem que fazer isto.

Deixe de ser teimoso, Sérgio. Quem já usou ponteiros em C ou já programou em assembler tem absoluta certeza de que Java não disponibiliza ponteiros ao programador em sua sintaxe.

[]s
Luca

cv1

Sergio, as classes dos pacotes sun.* sao detalhes de implementacao da JVM da Sun. Sendo assim, elas podem fazer o que quiserem, afinal, elas nao tem que se preocupar com a portabilidade ou mesmo com a especificacao da JVM - afinal, elas estao abaixo disso. Em hipotese alguma, repito, [size=24]EM HIPOTESE ALGUMA[/size] voce deveria usar estas classes no seu codigo, a menos que voce esteja trabalhando na equipe da JVM da Sun, ou queira quebrar a cara quando uma nova versao da JVM sair (e quebrar o seu codigo), ou tentar rodar usando as JVMs da HP, BEA, IBM ou outros. Fim de papo.

Mais info em http://java.sun.com/products/jdk/faq/faq-sun-packages.html :wink:

saoj

Luca:
Deixe de ser teimoso, Sérgio. Quem já usou ponteiros em C ou já programou em assembler tem absoluta certeza de que Java não disponibiliza ponteiros ao programador em sua sintaxe.

:oops:

Mas eu nunca disse o contrário. Java não tem ponteiro na sintaxe, mas as referencias nada mais são que ponteiros (endereços de memória), tanto é que a Sun pode manipulá-los via sun.misc.Unsafe.

Acho que nós dois estamos certos, com vc um pouco mais certo. :slight_smile:

[color=blue]Errata:[/color]

Não é a VM, que como o Luca falou sempre terá acesso, mas sim a API Java, isto é, código Java e não código C da VM.

[color=blue]Corrigindo:[/color]

É para aqueles pouquíssimos casos críticos onde o código Java precisa de acesso direto ao enderaçamento físico de memória RAM

[color=#444444][/color]

saoj

[color=red][size=24]Não estou usando sun.misc.Unsafe, e não usarei sob hipótese nenhuma.[/size][/color] Não porque vc está falando, mas porque a Sun quando escreveu essa classe insegura conforme o nome já diz, TRAVOU O SEU USO PARA QUALQUER CLASSE QUE NÃO SEJA DO PACOTE JAVA.*. :smiley:

Se vc descompilar o código da classe sun.misc.Unsafe vai ver que ela checa via reflection qual é a classe que está chamando ela. Se for uma classe fora do pacote java.* vc recebe uma Exception. Única possibilidade para eu usá-la seria reescrevendo as APIs do Java e substituindo-as classes na minha Virtual Machine.

CV, a questão não é sobre o sun.misc.Unsafe, nem sobre se eu quero ou não manipular ponteiros, e sim sobre se java tem ponteiros ou não. É como se Tostines vende mais porque está sempre fresquinho ou se é fresquinho por que vende mais.

louds

Java não tem ponteiros, tem referencias. É IMPOSSIVEL Java ter ponteiros, dado que a máquina virtual java não tem essa capacidade.

Olha a droga da especificação e você vai ver que ela opera em cima de referencias entre objeto e não diz que precisa existir um heap no senso comum de programas C.

Agora oque a JVM da Sun faz na implementação dela, tanto faz, por que é uma implementação, não é a linguagem >>>Java<<<.

Quanto a class sun.misc.Unsafe; essa classe não acessa memoria ou tão pouco faz operações sob ponteiros. Ela é apenas uma classe de marcação para compilação semântica usada pela HotSpot. Ou seja, Java continua não tendo ponteiros.

Mas essa discussão está tão produtiva quanto argumentar se a parafina usada na produção do arroz foi refinada de óleo Brent ou WTI ou se for óleo sweet muda o gosto da mistura.

saoj

“louds”:
Agora oque a JVM da Sun faz na implementação dela, tanto faz, por que é uma implementação, não é a linguagem >>>Java<<<.

Certo, veja a errata acima.

Ela te retorna o endereço físico (ponteiro) de um objeto na memória RAM, inclusive o endereço dos atributos de um objeto, para que eles possam ser acessados diretamente, não por eu e vc, mas por quem vai escrever APIs complexas como java.nio.

[color=red]Bomba: a classe Unsafe tem funções do tipo setMemory(address), putByte(address), getByte(address), ou seja, é possível através de um código 100% pure Java acessar diretamente um endereço físico de memória RAM.[/color]

Ou seja, se eu entro no JCP e proponho uma nova api java.lightspeedplane.*, eu posso trabalhar com ponteiros de memória via sun.misc.Unsafe. Pelo menos é o que me parece…

É aquilo. Falar que java não tem ponteiros é correto, mas as referencias não seriam ponteiros disfarçados e protegidos do programador ??? O que diferencia um ponteiro de uma referencia ??? Não vale falar que ponteiro vc pode fazer aritimética. Na minha cabeça a diferença é que uma referencia é protegida do programador e um ponteiro não. No resto é igual…

louds

Uma referência não é um ponteiro por que ela não tem a mesma semântica. Vide as primeiras JVMs, onde as referências não eram ponteiros devido ao uso de um GC com copy/compact, elas eram índices para uma tabela de objetos.

cv1

Nao eh 100% Pure Java, justamente pelo fato de usar uma classe sun.*, diacho. E nao sou eu quem ta dizendo isso, eh a propria documentacao da Sun, que voce deveria ter lido quando eu te mandei o link :wink:

Como queriamos demonstrar, essa discussao nao tem o menor sentido :mrgreen:

saoj

100% pure Java está errado mesmo no meu contexto. Tem razão, cv. A frase certa é:

Bomba: a classe Unsafe tem funções do tipo setMemory(address), putByte(address), getByte(address), ou seja, é possível através de um código Java acessar diretamente um endereço físico de memória RAM.

Essa discussão ficou inútil mesmo. Peço desculpas pela minha teimosia. É que eu fiquei impressionado quando descobri esse sun.misc.Unsafe no código do Java NIO.

Câmbio desligo…

louds

O Sergio está usando isso aqui http://wiki.yak.net/424 [color=red]CUIDADO AO VISITAR O LINK[/color]

Sergio, só para ser mais conclusivo, sun.misc.Unsafe não é java em nenhuma de suas possiveis formas. Sabe o porque? Ela tem métodos nativos que não são implementaveis via JNI.
De fato, o HotSpot quando encontra esses métodos os sustitui pelo código apropriado para usar ponteiros. Logo isso não é java nem a pau. A jikesrvm usa um mecanismo semelhante, caso queira estudar mais a fundo.

Luca

Olá

  1. Fortran tem referência desde sempre mesmo no tempo em que a gente acessava a memória diretamente sem toda esta questão de memória protegida e coisas assim. Mas Fortran pelo que eu saiba não tem ponteiros (pelo menos até antes do Fortran 77, pode ser que no 90 já tenha)

  2. Haver coisas com nome setMemory(address), set ou getByte(address) não quer dizer que seja acesso a memória direto e nem mesmo que tenha ponteiros. Quando eu uso ponteiro em C muitas coisas ocorrem por baixo dos panos antes que eu possa me convencer que estou acessando a memória diretamente, principalmente programando em WinNT/2000/XP. No DOS eu sabia que meus ponteiros estavam lá no segmento real abaixo de 640Kb.

  3. Ponteiro sem aritmética com ponteiros é a mesma coisa que um automóvel sem eixos, rodas, motor, carroceria, bancos, volante e adesivo do Framengo.

[]s
Luca

cv1

E, ainda bem, nao fez falta ate hoje - a manipulacao de arrays do Java, apesar de ainda ser bem lerdinha perto do que se estava acostumado a fazer em C, assembly ou outra linguagem pra macho, resolve todos os pepinos que so dava pra resolver com aritmetica de ponteiros – (d)efeitos especiais otimizados em imagens e FFTs, por exemplo. Alias, eu discordo do seu requerimento por um adesivo do mengao pra um automovel ser classificado como tal. :mrgreen:

louds

O problema é que ponteiros são muito mais faceis de usar para navegar dentro de arrays que índices em Java. Seria muito legal se tivessemos um ArrayIterator que, assim como strings, tem operator overloading.

Enquanto em C você só passa o ponteiro, em java você precisa do array e do índice, 2x mais coisas.

int.iterator i = new int[10].iterator;
while(i) { //converte para boolean, indicando se ainda é válido para leitura
   System.out.println(*i); //desreferencia ele :)
}

Java deveria ter bounded pointers. :cry:

fmeyer

Senhor amado … contaminacao pura ,… hehehe

arianrp

Ok pessoal,

vc estão falando de passagem por referência dentro da própria linguagem : de Java para Java , de C/C++ para C/C++.
E se for Java para C/C++???

Eu tenho a seguinte situação:
eu quero acessar objetos no Java pelo C via JNI usando passagem por referência pois o volume de dados pode ser imenso e eu não quero ter que fazer a JVM duplicar minhas variáveis na memória passando parâmetros por valor pra lá e pra cá.

O que acontece é que temos uma DLL desenvolvida em C e ela é utilizada em uma linguagem que aceita acesso direto a ponteiros, o que fazemos então é fornecer para a DLL os endereços dos valores a serem calculados e depois é só pegar os resultados.

Estamos estudando a migração do sistema para Java, vamos continuar usando essa DLL até que se tenha tempo e dimdim pra migrar toda o código.

Com JNI eu consigo acessar objetos Java e seus atributos,mas acho que ainda assim é por valor.
Vejam nesse código :

JNIEXPORT void JNICALL Java_com_Exemplo_metodo(JNIEnv *env, jobject obj_this){
jclass class_Exemplo = (*env)-&gt;GetObjectClass(env,obj_this);
jfiedID id_atributoA = (*env)-&gt;GetFieldID(env,class_Exemplo,"atributoA","D");
jdouble atributoA = (*env)-&gt;GetDoubleField(env,obj_this,id_atributoA);

atributoA = atributoA * 2;
(*env)-&gt;SetDoubleField(env,obj_this,id_salario,salario);

Se para modificar uma variavel em uma classe java eu preciso usar o metodo SetXXXField isso cheira a passagem por valor. Na verdade só pode ser passagem por valor.

Na própria assinatura de um método JNI em C temos o parâmetro que referencia o ponteiro da estrutura JNIEnv, que faz referência ao endereço na memória a uma estrutura com as funções JNI da JVM. Isso é uma prova de que é possível utilizar passagem por referência entre Java e C.
Ta certo que é a própria implementação da JVM, é muito baixo nível, mas por mais baixo nível que seja, deve haver uma forma disponível para referenciar um endereço de memória.

....(JNIEnv *env,...

Eu vi em algum lugar que isso se faz utilizando-se arrays, mas ainda não encontrei nenhum material esclarecedor que falasse sobre isso.

alguém manja???

T

A semântica da passagem de parâmetros não varia se você usa código nativo (public native etc…) ou não.

A passagem de objetos do Java para o Java, ou para o JNI/C++ é sempre passar uma referência por valor.

Não há cópia ou clonagem de objetos (passagem do OBJETO por valor).

Algo que é possível em C# mas não em Java, por exemplo, é passar uma referência por referência:

object obj = new object();
object obj2 = obj;
metodo (ref obj);
Console.WriteLine (obj2 == obj); // pode ser que obj seja modificado pelo método "metodo", apontando para um outro objeto, portanto nem sempre vai imprimir "true".

Mas em Java só é possível passar essa referência por valor:

Object obj = new Object();
Object obj2 = obj;
metodo (obj);
System.out.println (obj2 == obj); // A referencia a obj não pode ser modificada pelo método "metodo", portanto sempre vai imprimir "true".
C

Aqui tem algo. Basicamente, você tem que passar um array de tamanho 1 (se você passar um tipo primitivo, não consegue mudar o valor dentro da biblioteca em C, se passar um array, pode - eu acho isso gambiarra, mas funciona bem).
Nesse exemplo, você tem uma classe java que dobra o valor da variável:

public class DobraJNI {

	private static native void dobra (int[] n);
	static {
		System.loadLibrary("DobraDll");
	}

	public static void main (String[] args) {
		int[] i = Integer.parseInt(args[0]);
		System.out.print("2 x " + i[0] + " = ");
		dobra(i);
		System.out.println(i[0]);
	}
}

E agora, o código da biblioteca:

#include <jni.h>
#include "DobraJNI.h"

JNIEXPORT void JNICALL Java_DobraJNI_dobra (JNIEnv *env, jclass jc, jintArray anIntArray) {
  
	jint* valor;	

	valor = env->GetIntArrayElements (anIntArray, NULL);
	valor[0] *= 2;
	env->ReleaseIntArrayElements (anIntArray, valor, 0);
}
K

Olha, sou novo do mundo do Java e já abandonei o C/C++, porem uma das vantagens que me lembro em relação ao uso de ponteiros em C/C++ era na passagem de parâmentros para algu método. Ponteiros deixava a tarefa mais rápida, visto que não era necessário passsar todo o “pacote” para o método. Mas e em Java como fica. Por exemplo: caso eu tenha que passar uma lista emcadeada com 500 nodos para um método, como faço???

Abraço a todos!!!

OBS: Essa postagem não é uma crítica a qualquer um dos envolvidos no diálogo. Apenas pergunto porque repito, sou novo no mundo do Java e tenho algumas dúvidas.

feltraco

Essa discussão denovo
NNNNÃÃÃÃÃÃÃOOOOO…

rs rs rs rs

K

Sei que não devo “remexer o passado”, mas minha dúvida ainda não foi respondida!!!

qmx

vc tá passando só a referencia do objeto que está dentro do heap da vm

pode continuar a dormir tranquilo

e chega de ressuscitar posts!!! :twisted:

danieldestro

Ele só passa uma cópia do valor se o argumento for do tipo primitivo.
Mesmo que seja passado um array de primitivos, ele passa referência, pois um array é um objeto.

T

De modo geral, se você pensar bem como é que o Java funciona, ele trabalha mais com ponteiros que o próprio C++. Estranho? Não. É que em C++ é possível você passar objetos por valor:

#include &lt;string&gt;
using namespace std;
/**
 * Este método recebe a string de entrada, e retorna a mesma string, só que concatenada com a string "1":
 * @param s A string de entrada (copiada por valor)
 * @return A string de retorno.
 */
string appendOne (string s) {
    s = s + "1"; // isto não altera a string original :P
    return s;
}

E isso não é possível em Java - você só pode passar , por valor, uma referência a um objeto.

rodrigo.bossini

Mesmo sendo esse um tópico bem antigo faço questão de dar minha opinião.

No contexto de linguagens de programação, ponteiro é uma variável capaz de armazenar o endereço de outra variável.

Entrando no contexto de C++, ponteiro é também uma variável capaz de armazenar o endereço de outra variável E que permite a conhecida artimética de ponteiros.

Pensando dessa forma, analise a seguinte frase:

Java tem ponteiros que não permitem aritmética de ponteiros.

O que tem de errado nisso tudo?

P

[color=green]Oh… Não é sobre as conversas de antes de todos. Mas posto aqui neste post, pois vejo que mesmo o post estando antigo, temos várias cabeças com várias opiniões interessantes que já deram a este, um grande conteúdo em conhecimento sobre o assunto.

Vocês mais velhos na linguagem, entendem melhor sobre a linguagem. DE NOVO: Eu não tô aqui para reviver a MESMA QUESTÃO que foi iniciada neste post, estou aqui para aproveitar o grande conteúdo deste, e adicionar algo mais.

Estou ciente de que posts antigos não devem ser revividos. Mas pensem neste papilo antigo como conhecimento. Um conhecimento que foi discutido durante tempos e tempos por profissionais de todas as áreas e muitos que conhecem a essência da linguagem de programação. Então não vejo motivo para não aproveitar este caderninho de anotações e incrementar alguma coisa nele. Acredito que conhecimento não deve ser jogado fóra assim, de maneira tão “crua”. Por isso não acho necessidade em criar um novo post sobre isso. Provavelmente iam vir falando: “lá vem de novo outro com a mesma 2$¨”. Então também foi por isso.

Mas antes que alguém venha com argumentos contra os meus, peço logo desculpa por estar sendo talvez um ignorante e ter achado que poderia aproveitar isso.[/color]

------------------------ MINHA DÚVIDA -------------------------

Acredito que muitos aqui já leram o livro “Java como programar 6ª edição” da editora Deitel. Eu estava começando a estudar o uso da classe RandomAccessFile e notei que na página 526, a classe de nome WriteRandomFile, na linha 84, tem um comando que de acordo com o livro (o autor e, não eu) fala que este comando tem um ponteiro ou uma espécie de ponteiro (eu não sei o que ele quis dizer, essa é minha dúvida. Afinal eu não entendo de ponteiros muito bem). Eu não entendi pois deus e o mundo diz que não existem ponteiros em Java. Eu concordo (pelos argumentos apresentados aqui por todos), mas, eu gostaria de entender qual a intenção do livro de dizer isso por exemplo:

[color=blue]“O aplicativo nas figuras 14.26-14.27 grava os dados em um arquivo que é aberto com o modo rw (para leitura e gravação). Ele utiliza o método seek RandomAcessFile para posicionar a localização exata no arquivo em que um registro das informações é armazenado. O método seek configura o ponteiro de posição no arquivo, como um local específico no arquivo relativo ao começo do arquivo, e o método RandomAcessAccountRecord write gera saída dos dados na posição atual no arquivo. O programa supõe que o usuário não insere números de conta duplicados.”[/color]

Depois no segundo parágrafo da página 528, ele diz isso:

[color=blue]“As linhas 84-85 chamam o método RandomAcessFile seek para posicionar o ponteiro de posição no arquivo na localização do objeto output de acordo com o byte calculado por (accountNumber - 1) * RandomAccessAccountRecord.SIZE. Os números de conta nesse programa estão no intervalor de 1-100. Subtraímos um do número de conta ao calcular a localização de bytes do registro.”[/color]

Olha eu não tô querendo colocar o código da classe toda pois acredito que vocês têm esse livro. Mas eu vou colocar como está a linha 84:

output.seek( ( accountNumber - 1) * RandomAcessAccountRecord.SIZE );

output é um objeto RandomAcessFile.
accountNumber é uma variável criada que receberá um número de 1 a 100 do usuário que deseja criar uma conta.
RandomAcessAccountRecord é uma classe criada anteriormente cujo sua função é ler um registro e/ou armazenar dados ao arquivo (que é gerado depois).

Eu no começo pensei que ele multiplicava, já não tinha entendido. Mas quando ele mencionou a palavra ponteiro, aí piorou…

Se alguém puder me ajudar, eu ficaria realmente feliz e grato. Tô aqui para tirar dúvida, não gerar brigas e etc…

Obrigado pela atenção de todos.

J

saoj:
public class Exe { int numero; Exe teste1; Exe teste2; }

Java tem ponteiro sim, só que aqui o nome é referencia. Vc só não tem acesso direto ao endereço de memória que ele representa, e por isso vc não pode manipular esse endereço.

A sun pode, através da class sun.misc.Unsafe.

A sun podia liberar isso para nós…

E

Troque a palavra “ponteiro” (a tradução é realmente infeliz) por “cursor” ou “índice”. Você fica mais à vontade?

J

entanglement:
Plig:

Eu no começo pensei que ele multiplicava, já não tinha entendido. Mas quando ele mencionou a palavra ponteiro, aí piorou…

Troque a palavra “ponteiro” (a tradução é realmente infeliz) por “cursor” ou “índice”. Você fica mais à vontade?

Acho que apontador seria mais indicado.

P

entanglement:
Plig:

Eu no começo pensei que ele multiplicava, já não tinha entendido. Mas quando ele mencionou a palavra ponteiro, aí piorou…

Troque a palavra “ponteiro” (a tradução é realmente infeliz) por “cursor” ou “índice”. Você fica mais à vontade?

Oh! Com certeza! Brigado pela ajuda entanglement!!! Tipo, bem… Eu acho que entendi… Na verdade ele meio que estaria escolhendo a posição de cada registro no arquivo? Seria isso?

E qual o motivo dele ter multiplicado todo aquele fuzoê ali? Ele diminuiu o número da conta do usuário por um, e logo em seguida, multiplicou isso por 72 (SIZE tem como valor 72). Um amigo meu me disse que esse 72 serve como valor máximo de cada registro. O livro diz que isso serve como consulta rápida e que os registros ficam melhor organizados e mais fáceis de serem achados em um arquivo (O assunto é Arquivo de acesso aleatório). Mas novamente, não entendi o cálculo que ele fez. De acordo com isso, o resultado seria x - 1 * 72 (onde x está entre 1 e 100. 100 é o máximo número de usuários que podem existir). Juro que não entendi o motivo deste cálculo. Perdão se for algo besta que eu não tenha prestado atenção. Mas eu não entendi. :frowning:

OBS: Estou num exemplo em que ele cria registro e tenta colocar em um arquivo.dat. Ele utiliza várias classes para manipular este arquivo.

Mais uma vez, agradeço a atenção de todos, de coração mesmo.

Abraços!

Criado 18 de abril de 2005
Ultima resposta 5 de fev. de 2010
Respostas 44
Participantes 19