Java 1.7 (Dolphin) vai ter ponteiros?

setAppelationMode(true);
setForcacaoDeBarraLevel(ForcandoABarra.EXTREME);

Tinham pedido alguns exemplos de obter ponteiro inválido em java e de fazer aritmética de ponteiros. Pois bem, lá vai.

Agradecimentos ao meu amigo Alcides Liberali.

import sun.misc.Unsafe;
import java.lang.reflect.Field;

/**
 * @author Victor Williams Stafusa da Silva
 * O ministério da saúde adverte: Esta classe causa câncer e
 * severos outros danos a saúde. Não existem níveis seguros
 * para o consumo das substâncias aqui presentes.
 *
 * Agradecimento: Alcides Liberali
 */
public class ApelacaoSemNocao {
    public static void main(String[] args) throws Exception {

        // Total appelation here!
        Field f = Unsafe.class.getDeclaredField("theUnsafe");
        f.setAccessible(true);
        Unsafe unsafe = (Unsafe) f.get(null);

        Object h4ck3r = new Object();

        // Colocando um belo lixo de memória aqui.
        unsafe.putLong(h4ck3r, 0, 0x7777777777777777L);

        // Ops, obtém um ponteiro inválido aqui!
        Class<?> lollollol1one = h4ck3r.getClass();

        // CRASH!
        lollollol1one.toString();
    }
}
import sun.misc.Unsafe;
import java.lang.reflect.Field;

/**
 * @author Victor Williams Stafusa da Silva
 * PERIGO: Crianças, não façam isso em casa.
 * Nunca, nunca, jamais, never, em hipótese alguma use isso em um ambiente de produção.
 * O uso deste programa é proibido para menores de 256 anos de idade.
 *
 * Agradecimento: Alcides Liberali
 */
public class AritmeticaDePonteiros {

    private static class PointerGambi1 {
        public long valor;
    }

    private static class PointerGambi2 {
        public Object valor;
    }

    private static final String[] array = {
        "cenoura",
        "batata",
        "uva",
        "pizza",
        "maionese"
    };

    public static void main(String[] args) throws Exception {

        // Total appelation here!
        Field f = Unsafe.class.getDeclaredField("theUnsafe");
        f.setAccessible(true);
        Unsafe unsafe = (Unsafe) f.get(null);

        // Obtém uns valores úteis.
        long ofg1 = unsafe.objectFieldOffset(PointerGambi1.class.getField("valor"));
        long ofg2 = unsafe.objectFieldOffset(PointerGambi2.class.getField("valor"));
        int offset = unsafe.arrayBaseOffset(String[].class);
        int scale = unsafe.arrayIndexScale(String[].class);

        PointerGambi1 g1 = new PointerGambi1();
        PointerGambi2 g2 = new PointerGambi2();
        unsafe.putObject(g1, ofg1, array); // Converte ponteiro em long (ou seria referência em long?)
        int t = unsafe.getInt(array, 8L); // Ou seja, t = array.length, que é o mesmo que *(&array + 8).

        // Itera o array.
        for (int a = 0; a < t; a++) {
            // Calcula a posição do elemento via aritmética de ponteiros (ou seria aritmética de referências?)
            long endereco;
            if (scale == 4) { // Para processadores de 32 bits (aqui a portabilidade foi pro saco!)
                endereco = unsafe.getInt(array, offset + 4 * a);
            } else if (scale == 8) { // Para processadores de 64 bits.
                endereco = unsafe.getLong(array, offset + 8 * a); 
            } else {
                throw new Exception("Escala não suportada: " + scale);
            }

            // Usa o g2 como um iterador.
            unsafe.putLong(g2, ofg2, endereco); // Converte long em ponteiro (ou talvez long em referência?)

            // Mostra o elemento.
            System.out.println(g2.valor);
        }
    }
}

[quote=thingol]"Variáveis de closure"? Acho que você está se referindo a isto aqui:

...
public {int, int => int} x;
...
x = Math#max(int, int);
int p = x.invoke (200, 300); // p recebe 300
...
x = {int r, int s => r + 3 * s };
p = x.invoke (200, 300); // p recebe 1100

[/quote]

sim, era isso que me referia. x é uma “variável de closure”. A questão é se isso é uma variável de objeto, ou não.
Olhando assim parece mais um método do que um Objecto. Sim, o método é um objeto tb… é só isso ? Possibilitar Método-Objecto ?
O seu exemplo de x= math#max() deixa isso bem claro. ( isso é official ?)

quando vc diz “pode” quer dizer “está proposto que o java tenha isto” ou “em tese , teoricamente, poderia fazer isto” ?

Obrigado ao sergiotaborda e ao thingol pelas respostas sobre o assunto, com certeza preciso ler muito mais ainda.

Alguém tem por aí o exemplo com catch múltiplo para eu observar?

Ah, victorwss… que monstro é isso? Hahahaha. Agora acho que podemos afirmar que java tem ponteiros?

[quote=ramilani12][quote=sergiotaborda]

[/quote]

Sergio por esse motivo entendo o seu ponto de vista.
Mas entenda que java trata de alocação de objetos em memória através da referência ,agora como ele referencia esse objeto na memória?,esta é questão.

Em java os ponteiros/referencia são manipuláveis pelo programador?
Não, isso é de responsabilidade da JVM, a maiora das JVM´s utiliza um handle: é um pointer que indica um outro pointer (aqui é a questão que disse acima)

É obvio para não se preocupar com memória é relativo , mas certas responsabilidades do programador foram substituidas por uma JVM(em relação a referencia de objetos na memoria)

[/quote]

Não vi o Sérgio falando nada diferente disso, apenas deu uma explicação conceitual sobre ter ponteiros e poder ou não manipulá-los.

Compreensão de texto, está faltando para muitos …

[quote=sergiotaborda][quote=thingol]"Variáveis de closure"? Acho que você está se referindo a isto aqui:

...
public {int, int => int} x;
...
x = Math#max(int, int);
int p = x.invoke (200, 300); // p recebe 300
...
x = {int r, int s => r + 3 * s };
p = x.invoke (200, 300); // p recebe 1100

[/quote]

sim, era isso que me referia. x é uma "variável de closure". A questão é se isso é uma variável de objeto, ou não.
Olhando assim parece mais um método do que um Objecto. Sim, o método é um objeto tb… é só isso ? Possibilitar Método-Objecto ?
O seu exemplo de x= math#max() deixa isso bem claro. ( isso é official ?)

quando vc diz "pode" quer dizer "está proposto que o java tenha isto" ou "em tese , teoricamente, poderia fazer isto" ?

[/quote]

a) Closures em C# e na proposta BGGA para o Java são implementados usando classes anônimas. Portanto essas variáveis que contém closures, na verdade são de um tipo especial que é uma classe anônima. Ou seja, como todas as variáveis (exceto as que são de tipos primitivos), elas irão referir-se a objetos.
b) Essa declaração maluca de interface que estende uma closure está também na proposta BGGA, mas acho que ninguém em são consciência vá usar uma coisa dessas.
c) Quando alguém declara isto aqui:

{int, int => int} x = Math#max(int,int);

está na verdade fazendo algo parecido com isto aqui:

Closure2<Integer,Integer,Integer> x = new Closure2<Integer,Integer,Integer>() {
    public Integer invoke (Integer a, Integer b) {
        return Math.max (a, b);
    }
}

É claro que em vez de termos esse tipo genérico “Closure2” temos algo um pouco mais complexo, mas isso é um detalhe de implementação que pode ser alterado do protótipo da proposta BGGA para o produto final, caso isso venha a ser adotado no Java 7 ou 8.

O catch múltiplo, embora não seja algo que esteja definido na proposta BGGA (http://www.javac.info ) , é algo que está programado no protótipo (também pode ser baixado de http://www.javac.info ). É algo bem simples:

try {
    ....
} catch (FileNotFoundException | ObjectStreamException ex) {
   ex.printStackTrace();
}

Que é uma abreviatura bem cômoda para:

try {
    ....
} catch (FileNotFoundException ex) {
   ex.printStackTrace();
} catch (ObjectStreamException ex) {
   ex.printStackTrace();
}

Usando o velho e bom princípio “DRY” (Don’t Repeat Yourself". )

É óbvio que quando listamos 2 ou mais exceções, só podemos chamar os métodos que são comuns a elas (não sei se o Gafter impõe que os métodos estejam na superclasse, ou se eles simplesmente podem ter o mesmo nome).

[quote=Kenobi][quote=pcalcado]
Ponteiro é uma coisa, referência (remota ou local) é outra.[/quote]

E qual a diferença ? Sempre entendi que ponteiro é algo que aponta à uma referência. Você ter manipulação direta sobre eles é outra questão. Poderia explicar a diferença ?
[/quote]

Imagine que a memória é um grande array. Se sua variável guarda um índice para o array ela é um ponteiro -e você a desreferencia, usando algo como Obj a = memoria[ponteiro];, para pegar o valor- se ela guarda uma referência direta para o objeto armazenado no array ela é uma referência.

Em C++ a diferença é gritante. Dê uma olhada no link que passaram antes.

[quote=victorwss]setAppelationMode(true);
setForcacaoDeBarraLevel(ForcandoABarra.EXTREME);

Tinham pedido alguns exemplos de obter ponteiro inválido em java e de fazer aritmética de ponteiros. Pois bem, lá vai.

Agradecimentos ao meu amigo Alcides Liberali.
[/quote]

Pela sua linha de raciocínio eu posso dizer que Java “possui” Ruby já que existe uma biblioteca que permite executar Ruby.

[quote=pcalcado][quote=victorwss]setAppelationMode(true);
setForcacaoDeBarraLevel(ForcandoABarra.EXTREME);

Tinham pedido alguns exemplos de obter ponteiro inválido em java e de fazer aritmética de ponteiros. Pois bem, lá vai.

Agradecimentos ao meu amigo Alcides Liberali.
[/quote]

Pela sua linha de raciocínio eu posso dizer que Java “possui” Ruby já que existe uma biblioteca que permite executar Ruby.[/quote]

Hã? O que ruby tem a ver com a história?
O negócio é que aqueles programas não fariam o que fazem se as referências no java não fossem implementadas como ponteiros.

[quote=victorwss]
Hã? O que ruby tem a ver com a história?
O negócio é que aqueles programas não fariam o que fazem se as referências no java não fossem implementadas como ponteiros.[/quote]

O que você mostrou foi uma biblioteca que não faz parte da linguagem Java (faz da implementaçãod a JVM da Sun, provavelmente). JRuby é exatamente isso, uma biblioteca que não faz parte de java mas faz java suportar Ruby.

Acho que ninguém aqui acha que as referências não são implementadas por ponteiros, até porque a JVM é em C++. Claro que isso não faz delas ponteiros.

Olá

O Fortran sempre teve referências muito antes de aparecer o termo ponteiro na área de TI. O conceito de ponteiro surgiu com o C, nenhuma linguagem mainstream tinha isto antes. E o C só deslanchou mesmo como linguagem muito usada depois dos micros. Aqui no Brasil onde os mainframes IBM dominavam amplamente o mercado, antes dos micros, o C só era usado nas universidades.

Este tópico tenta provar que ter um cachorro morto enterrado no jardim é o maior barato. O cara tem mas não pode fazer nada com ele.

Eu vivi no tempo em que o Java surgiu e lembro claramente de todo o marketing feito em cima do Java justamente por não haver ponteiros na linguagem para o programador usar. Nunca vi em livro nenhum de Java básico alguma linha ensinando como usar ponteiro em Java. E nunca vi em nenhum livro de programação o termo referência sendo confundido com o termo ponteiro como querem demonstrar neste tópico.

E nunca vi ninguém se preocupar como a linguagem era implementada. Como disse antes, o compilador Fortran sempre teve tabelas de símbolos implementadas usando estruturas de dados mais poderosas do que a linguagem disponibilizava para o programador e nunca vi nenhum programador dizer que a linguagem Fortran tinha tabelas de símbolos.

[]s
Luca

seria uma boa se java deixasse vc usar ponteiros… mas opcionalmente que nem o C# seria algo otimo…

Não fala besteira, manipular ponteiros diretamente é algo inerentemente inseguro. Embora sem dúvida ponteiros dêem uma ampla flexibilidade e um controle quase total da CPU, eles também são a porta de entrada para que muita merda aconteça. Sim, a LINGUAGEM java não tem ponteiros, mas isso não significa que eles não existam no AMBIENTE java.

E se por algum motivo, você REALMENTE precisa de ponteiros, acho que o JNI seria a melhor saída.

pcalcado: Sim, sun.misc.Unsafe é algo bem específico da JVM da Sun e não faz parte do conjunto de classes públicas do java e nem nunca deverá fazer. O nome da classe já diz o que ela é.

Olhando um pouco para o passado, vejo que ponteiros tendem a ser traumatizantes para boa parte dos programadores C e C++, em especial aqueles que querem migrar. Então em uma linguagem que não os tem (embora ainda estejam escondidos lá dentro), seria uma boa idéia jogar o marketing nesta direção.

O problema é pegar alguém que não saiba lidar com ponteiros fazendo uma coisa dessas… inclusive um experiente sempre deixa passar algum memory leak.

O problema de você deixar um usuário da linguagem usar ponteiros é que você acaba tendo de diferenciar entre uma região de memória onde o garbage collection deve ser bloqueado (memória fixa) e outra onde o garbage collection pode prosseguir normalmente.
É que ponteiros do C/C++ normalmente apontam para memória “fixa”.
Isso acarreta vários problemas que são difíceis de resolver sem deixar seu programa MAIS LENTO.

Você que usa ponteiros em C# achando que as coisas vão ficar mais rápidas vai se surpreender vendo que elas ficam é mais lentas, devido a esses problemas esquisitos.

(Aham, em Real-Time JAVA existe o conceito de memória fixa, não sujeita a garbage collection, mas a manipulação dessa memória não é arbitrária como se fosse com ponteiros, e tal memória deve ser alocada com cuidado. )

[quote=Luca]Olá

Eu vivi no tempo em que o Java surgiu e lembro claramente de todo o marketing feito em cima do Java justamente por não haver ponteiros na linguagem para o programador usar. Nunca vi em livro nenhum de Java básico alguma linha ensinando como usar ponteiro em Java. E nunca vi em nenhum livro de programação o termo referência sendo confundido com o termo ponteiro como querem demonstrar neste tópico.

E nunca vi ninguém se preocupar como a linguagem era implementada. Como disse antes, o compilador Fortran sempre teve tabelas de símbolos implementadas usando estruturas de dados mais poderosas do que a linguagem disponibilizava para o programador e nunca vi nenhum programador dizer que a linguagem Fortran tinha tabelas de símbolos.
[/quote]

Mas é exactamente esse o problema. Vc está distorcendo o marketing.
O que o marketing do java afirma é que ele não tem “Tipo de Dado Ponteiro” (pointer data type) que é diferente de “ponteiro” (pointer). E isso é verdade. Não existe , em java, e nem em nenhuma outra linguagem de alto nivel o conceito de uma variável que contém outra variável. Tudo bem.
A distorção é que vc supoe que isso significa que não existem ponteiros (variável de endereço) e isso é que é falso porque vc está tentando inverter uma implicação como se fosse uma equivalencia.

pointer data type => pointer

Nem no C é uma equivalencia. Se fosse não seriam necessárias referencias e ponteiros juntos.

O ponto é que é evidente que Java usa ponteiros, não apenas de forma enterrada, mas de forma explicita. Se mais nenhum exemplo o convence pelo menos o == deveria. A menos que consiga explicar o que ele faz sem usar o conceito de ponteiro.
O conceito de ponteiro é muito simples: Variável que contém um endereço. Se esse endereço é na memoria fisica, na memoria virtual, em uma tabela de alocação , não importa.
Esqueça C um momento e a teoria compada das linguagens. Foque apenas no java.

Integer a = new Integer(1);
Integer b = new Integer(2);

if (a==b){
  a=b; 
}
a=null

1)O que significa “Integer a” ?
2)O que significa a==b ?
3)O que significa a=b ?
4)O que significa a=null ?

Tente explicar estas operações sem utilizar o conceito de ponteiro (do C) nem o de referencia ( do C nem do Java)
Vai ver que é muito simples, mas precisa do conceito de “apontar” em algum lugar da sua explicação. Não é mesmo ?

Este é um exercicio simples se quer entender porque o Java tem ponteiros.
Se não quiser esqueça… quem entende, entende e para quem não entende … est lasse.

Olá

Falei no passado e disto tenho certeza que no lançamento do Java isto era apregoado com vantagem.

OK, OK, você venceu. Se você quer, referência passa a ser a mesma coisa que ponteiro, COBOL, FORTRAN 66, ALGOL todos tem ponteiros e não se fala mais nisto. Só não coloque como minhas coisas que eu não escrevi.

[]s
Luca

besteira restingir algo so pq algum inexperiente possa fazer merda…
se vc não tem certeza doque esta fazendo simplismente não faça desta forma… simples…
seria legal ter a liberdade de manipular ponteiros… mas o problema é que quem faz este tipo de coisa e a jvm para delegar isto ao programador estara passando por cima da jvm…
mas ponteiros são legais… basta saber manipular de forma correta…

[quote=luistiagos]besteira restingir algo so pq algum inexperiente possa fazer merda…
se vc não tem certeza doque esta fazendo simplismente não faça desta forma… simples…
seria legal ter a liberdade de manipular ponteiros… mas o problema é que quem faz este tipo de coisa e a jvm para delegar isto ao programador estara passando por cima da jvm…
mas ponteiros são legais… basta saber manipular de forma correta…[/quote]

O problema é que o uso de ponteiros compromete a segurança do java, compromete a robustez, compromete a portabilidade e compromete mais um monte de coisas. Obviamente, que para usar ponteiros corretamente tem que ser experto, e decerto, se forem usados corretamente nenhum destes problemas aparece. O porém é que usá-los errado é muito mais fácil do que usá-los certo.

Obviamente, quem for fazer merda, faz merda com qualquer coisa. Mas merda em ponteiro fede mais que qualquer outra merda. Então eles foram evitados até a morte.

Se você realmente precisa, use JNI, ou se quiser pode até apelar para o Unsafe (e fugir da inquisição depois).

A disponibilidade de ponteiros compromete o desempenho (porque você não pode usar um super-ultra-rápido algoritmo de “garbage collection” mas um algoritmo mais vagabundo, que permita ter regiões de memória fixa), e compromete sua sanidade mental - imagine como é tentar corrigir problemas de ponteiros - eu que já programei (e programo) muito em C e C++ é que digo.

Thingol, existem garbage collectors que funcionam com ponteiros e conseguem mover objetos mesmo na presença de interior pointer. De fato, pointeiros não impedem algorítmos avançados de GC, o que impede é tracing conservativo.