Java中的引用和C++中引用的区别

首先了解C++ 中引用的含义:“引用”即“别名”。C++中的引用代表的就是实际的存储空间。对其进行操作就是对存储空间进行操作。

而在Java中的引用:可以看做是C语言中的“指针”或者“地址”。对java中引用的属性(即指针指向的存储空间)进行操作才是有效的。

1)Java引用作为函数(方法)参数

Java的方法参数只是传值,引用作为参数使用时,会给函数内引用的值的COPY,所以在函数内交换两个引用参数是没有意义的,因为函数交换的是参数的COPY值;但是在函数内改变一个引用参数的属性是有意义的,因为引用参数的COPY值指向的对象和原引用指向的是同一个对象。

2)C++引用作为函数参数

由于C++引用传进去的就是“别名”,所以在函数内对其进行的全部操作都将直接作用于实际的对象存储空间上。

产生这个困惑的原因很可能是涉及到在函数(方法)中进行malloc(new)新的堆空间有关。其实这是一个比较有意思的问题。

Java中没有了指针,这种不便可以通过Java的引用特性得到弥补。即对于Java的任何对象,我们可以申明对象变量,但不产生实例,这样,把该变量指向具有实际实例的对象,即可实现同一实例对象的多个变量引用,如:

int x[]={1,2,3,4,5}, y[];

y=x;

for(int i=0; i<y.length; i++) System.out.print(“   ”+y[i]);

则完成了通过y对x的引用。从这个实际效果看,y在这里就很象C语言中的指针了。只不过对于“指针”y我们不能进行+或-这类算数运算,即Java的引用只能指向程序限定的能够访问的现存对象,所以Java的实现者认为它是灵活同时也是安全的。

但对于C或者C++中能够通过函数简单实现的两个数交换问题,即C++如下函数:

void swap(int &x, int &y) { int t; t=x; x=y; y=t; }

在Java中是否能够实现呢?

按照Java的规定,Java的函数参数在传递的时候有两种方式。对于基本类型,如int,double等作为函数参数传递时,采取的是传值方式。而对于对象,如数组、字符串等作为参数传递时,采用的是引用方式,即此时在函数中对传递的对象的修改将完全影响原对象。那能否对于对象利用引用完成值的交换呢?下面的程序充分地演示了这个问题:

public class test {

  public static void main(String[] arg) {

    int x1[]={1,2,3},x2[]={3,2,1};

    swap(x1,x2);//采用swap函数,即直接利用参数引用进行交换

    System.out.print("swap->X1:\t"); printarr(x1);

    System.out.print("swap->X2:\t"); printarr(x2);

    swapArray(x1,x2);//采用swapArray函数,利用对于对象的值的修改进行交换

    System.out.print("swapArr->X1:\t"); printarr(x1);

System.out.print("swapArr->X2:\t"); printarr(x2);

Object t;

    t=x1; x1=x2; x2=(int[])t;//在非函数调用中直接利用引用进行交换

    System.out.print("Tswap->X1:\t"); printarr(x1);

    System.out.print("Tswap->X2:\t"); printarr(x2);

  }

  public static void swap(Object x, Object y) {//直接利用参数引用交换

    Object t=x;

    x=y;

    y=t;

  }

  public static void swapArray(int x[], int y[]) {//对引用对象的值进行修改完成交换

    if(x.length!=y.length) return;

    int t[]=x.clone();

    for(int i=0; i<x.length; i++) x[i]=y[i];

    for(int i=0; i<y.length; i++) y[i]=t[i];

  }

  public static void printarr(int x[]) {//打印数组

    for(int i=0; i<x.length; i++) System.out.print(x[i]+"  ");

    System.out.println();

  }

}

在函数swap中,我们直接利用参数进行交换。在函数swapArray中,我们通过修改参数指向的两个数组的值进行交换。而在main函数没有进行函数参数传递的情况下,我们直接利用参数的引用进行了一次交换。

程序的运行结果如下:

swap->X1:     1  2  3 

swap->X2:     3  2  1 

swapArr->X1: 3  2  1 

swapArr->X2: 1  2  3 

Tswap->X1:   1  2  3 

Tswap->X2:   3  2  1 

从运行结果我们可以清楚地看到,函数swap实际没有完成交换,而函数swapArray和直接在main中利用引用进行的交换是成功的。从这里我们可以得知,虽然Java的引用可以实现C和C++的指针的类似的效果,这在主函数中的引用交换得到了证明。但是一但进行了函数的参数传递,这种引用方式的交换便实效了。虽然它的交换方式和主函数中利用Object引用t进行的交换方式相同。猜测其原因(因为我不是Java的实现者),只能说明,函数中的引用变量和主函数中调用的变量是不相同的。即在调用swap函数时,虽然将x1的引用传递给了x,x2传递给了y,x和y进行了交换,但x1和x2并没有进行交换。也就是说,在函数swap申明参数x和y时,实际另外真正的生成了与x1和x2完全不相干的引用,只不过x和y都同样指向了x1和x2罢了,即此时,数组对象x1和x2同时分别有两个指针x、x1和y、y1指向它们。这样的结果当然不能完成如C和C++类似的交换。唯一的办法是如swapArray函数中一样,不要试图交换,只能试图修改参数所指向的两个对象的值来达到交换的效果。

所以我得出的一个相关的结论是:Java永远也不能实现如C和C++一样的swap函数。

Java交换两个数

在java中没有指针的概念,java中时引用,但这一概念已经被淡化了这里有两种方法:

【1】使用全局变量进行数值传递

public class Swap{
    public Swap(int x,int y){         
       int z;
       z=x;x=y;y=z;
       a=x; b=y;
    }
    public void getInfo(){         
       System.out.println("交换后:a= "+a+",b="+b);
    }
    private static int a;         
    private static int b;
    public static void main(String args[]){     
       a=10;                                    
       b=8;
       System.out.printf("交换前: a="+a+",b="+b+"\n");
       F w1=new F(a,b);  
       w1.getInfo();
    }

}

【2】把用于交换的参数作为对象的一个变量

class T{                
    int t;
}
public class G {
    public static void main(String args[]){
        T a=new T();       
        T b=new T();
        a.t=8;
        b.t=10;
        System.out.println("交换前 :a="+a.t+"  ,b="+b.t);
        change(a,b);
        System.out.println("交换后 :a="+a.t+" ,b="+b.t);
    }
    public static void change(T a,T b){
        T c=new T();      
        c.t=a.t; a.t=b.t; b.t=c.t;   
    }
}


  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值