我如何在Java中使用指针?

149

我知道Java没有指针,但我听说Java程序可以使用指针创建,并且只有少数精通Java的人才能做到。这是真的吗?


2
无论如何,在Sun的实现中。 - Michael Myers
1
我可以使用那个指针地址吗? - user213038
7
Java对象的默认hashCode不是指针地址。仔细阅读hashCode的规定,你会发现内存中的两个不同对象可能会拥有相同的hashCode值。 - Amir Afghani
3
在64位和32位Java中,32位的哈希码不是地址。哈希码并不保证唯一性。当对象在空间之间移动并且内存被压缩时,对象的位置可能会改变,但是哈希码不会改变。 - Peter Lawrey
2
你可以用Java引用实现C++指针的90%功能,剩下的10%可以通过将引用封装在另一个对象中来实现(虽然我从未发现有必要这样做)。 - Richard Tingle
显示剩余3条评论
17个回答

1
像其他人说的那样,简短的回答是“不行”。
当然,你可以编写与Java指针交互的JNI代码。根据你想要实现的目标,也许这能帮你一些忙,也许不行。
你可以通过创建一个数组并使用该数组的索引来模拟指针。同样,这取决于你想完成什么任务,这可能有用,也可能没用。

1

来自名为《反编译Android》的书籍,由Godfrey Nolan所著。

出于安全考虑,在Java中不使用指针,因此黑客无法从应用程序中打破限制并进入操作系统。没有指针意味着其他东西(在这种情况下是JVM)必须负责分配和释放内存。理论上,内存泄漏也将成为历史,但有些用C和C++编写的应用程序因为程序员没有在适当的时候释放不需要的内存而臭名昭著——当然,任何阅读这篇文章的人都不会有这样的罪过。垃圾回收还应该使程序员更加高效,减少调试内存问题所需的时间。


我可能是一个奇怪的例子,但是我在使用Java时遇到的内存泄漏比C或C++更多,因为垃圾收集器没有触发。我似乎总是需要显式地调用垃圾收集器。并不是说我没有其他指针相关的错误,但是特别是对于内存泄漏,我在使用Java时遇到的情况比其他语言更多。 - ttbek

0

你可以,但不是完全的。你不能直接访问指针,但你可以有一个变量列表,它们指向同一个位置。几年前我偶然发现了一种方法。

我不确定为什么,在Java中当你将一个列表设置为等于另一个列表时,而不是复制所有信息,会创建一个指向原始列表的指针。我不确定它是否适用于所有形式的列表,但到目前为止,我测试过的都是这样的。我相信arrayList也有函数clone(),如果你想要一个真正分离的列表,可以绕过这个问题。

int[] example

public class Main {

    public static void main(String[] args){

        int[] alpha = new int[] {1,2,3};

        int[] beta = alpha;
        beta[0]=9;
        beta[1]=9;
        beta[2]=9;

        System.out.println("alpha: " + alpha[0] + ", " + alpha[1] + ", " + alpha[2]);
        System.out.println("-beta: " + beta[0] + ", " + beta[1] + ", " + beta[2]);
    }
}

arrayList 示例

import java.util.ArrayList;

public class Main {

    public static void main(String[] args){

        ArrayList<Integer> alpha = new ArrayList<>();
        alpha.add(1);
        alpha.add(2);
        alpha.add(3);

        ArrayList<Integer> beta = alpha;
        beta.add(4);
        beta.set(0, 5);

        System.out.println("alpha: " + alpha.toString());
        System.out.println("-beta: " + beta.toString());
    }
}

0
如果你想在Java中体验指针的感觉,我做了这个小东西: https://github.com/v22lel/C-Pointers-in-Java 但请记住,这些指针只分配在虚拟内存中,所以它们不使用真正的RAM,并且比普通的Java慢得多。这只是一个小小的有趣玩笑,不应该在项目中认真使用。

0

你也可以为字面量使用指针。你必须自己实现它们。对于专家来说,这是相当基本的 ;). 使用int/object/long/byte数组,你就有了实现指针的基础。现在任何int值都可以成为该数组int[]的指针。你可以增加指针,你可以减少指针,你可以乘以指针。你确实有指针算术! 这是实现1000个int属性类并拥有适用于所有属性的通用方法的唯一方法。你也可以使用byte[]数组而不是int[]

然而,我希望Java能让你通过引用传递字面值。类似于以下内容

//(*告诉你这是一个指针) public void myMethod(int* intValue);


-1
所有的Java对象都是指针,因为持有地址的变量被称为指针,而对象持有地址。所以对象是指针变量。

1
不,Java对象不是指针。它们相当于引用,具有不同的功能和语义。 - Danger

-4
Java 可以轻松地使用指针,只需知道数组名称是指向第一个索引的指针即可。这就是为什么当我们将数组传递给函数时,不需要编写它的方括号。因为数组是引用。

public class Main    
{
    public static void func ( int ptr1[] , int ptr2[] )
 {
      int temp;
      temp = ptr1[0];
      ptr1[0] = ptr2[0];
      ptr2[0] = temp;
      
 }
    
    public static void main(String[] args) {
        
        int x = 5;               int y = 8;
        
        // in c language
        //  int *p = &x;       int *q = &y;
        
        
        //  in Java
        int p[] = new int[1];
        int q[] = new int[1];
        
        p[0] = x;   // same as pointer
        q[0] = y;   // same as pointer
        
        func( p , q );  // passing address ( refrence )
        
        System.out.println( "  After Swap " );
        System.out.println( "x = "  + p[0] + "  " +  "y = " + q[0] );
        
    }
}



你没有在Java中展示指针,只是因为对于数组来说,将它们传递给方法的语法不包括[]。 要让C理解,你可以看一下https://dev59.com/THI-5IYBdhLWcg3w18d3 - cyberbrain

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接