• Java传参


    今天想起快排的实现,便用Java实现它,我发现一个swap(int a ,int b)交换方法不能改变两个数的值,好吧我Java基础好烂,用C传地址交换做过无数遍,但用Java还真没试过,上网找方法解决,看到一篇文章写得挺不错的。

    先来看下面这三段代码:

    //Example1:
    
    public class Example1
    
    {  
       static void check(int a)
    
       {
         a++;
       }
    
       public static void main(String[]args)
    
      { 
        int x=10;
    
        check(x);
    
        System.out.println(“Example1.x=”+x);}
    
    }
    
    //Example2:
    
    public class Example2
    
      {  
        static void check(StringBuffer obj)
    
          { 
             obj.append(“JAVA”);
          }
    
          public static void main(String[]args)
    
          { 
             StringBuffer x=new StringBuffer(“Hello   ”);
    
             check(x);
    
             System.out.println(“Example2.x=”+x);
          }
    
      }
    
    //Example3:
    
    Public class Example3
    
     {    
        static void check(String obj)
    
         { 
           obj=“JAVA”;
         }
    
         public static void main(String[]args)
    
        { 
           String x=”Hello   ”;
    
           check(x);
    
           System.out.println(“Example3.x=”+x);
        }
    
    } 

    编译运行结果是:

    Example1.x=10

    Example2.x=Hello JAVA

    Example3.x=Hello

    类Example1的结果是最容易理解的,因为此时向方法check(int a)传递的是一个整型变量,而整型变量是基本数据类型的一种。当向一个方法传递基本数据类型时(基本数据类型包括 byte,int,short,char,float,double以及boolean),传递的只是该数据内容的一个副本,因此无论方法针对该副本值做怎样的改变,都不会影响到被传入的数据本身。

    类Example2的结果也是比较容易理解的,因为此时向方法check(StringBuffer obj)传递的是一个StringBuffer变量,这个变量是对象型数据类型的一种。当向一个方法传递对象型数据类型(包括String, StringBuffer,类对象引用,接口引用和数组等)时,传递的是该数据对象的某个引用变量而不是对象内容本身,因此,在将引用变量x传入方法时,obj和x便同时对原来x所引用的对象(这个对象的内容是”Hello  ”)具有了引用关系,也就是说,obj和x都是对象(即”Hello  ”)的引用,由于JAVA对于对象的访问是通过访问对象的引用来完成的,因此,当方法对obj的引用对象内容进行改变时,实际上也是在针对x所引用的对象的内容进行改变,这自然导致了读者所看到的结果。

    但类Example3所显示的结果就令人费解了。这个例子颇像类Example2,传入方法的String也是一个对象型数据,按理说传入方法的就应该是引用而不是类似Example1的副本值,但结果恰好相反,方法并未对x所引用的对象造成任何影响。因此,有些教材就此定论,String对象是特例,只有String这个特例向方法传递对象内容的副本值,而其它对象型数据则传递对象引用,事实果真如此吗?

    种理解绝对是错误的!用户对传入方法的数据倒底是传值还是传引用的问题感到迷惑,其原因主要是用户对数据类型的使用机制不够了解。因而,在解释上述问题之前,先来清楚一下JAVA中数据类型的使用机制。

    JAVA中基本数据类型是在系统的栈中创建的,而对象型数据则是在堆中创建的。位于栈中的基本数据类型简化了调用机制,可以被直接调用而没有引用的概念,同时也抛弃了作为对象可以带来复杂属性设置的好处,属于轻装上阵,因而运行效率高;对象型数据正好相反,尽管运行效率低于前者,但可以向用户提供作为对象带来属性设置的好处,不过,用户必须也只能通过对象的引用变量来实现对对象内容的访问,不能象基本数据类型那样直接访问对象内容。例如有这样一句代码:

    String a;

    在这里,a并不是对象,而是可以访问对象的一个引用变量,一个对象可以有多个引用变量指向它,但每个引用变量却只能指向一个对象。那么对象在哪里呢?这时的对象还未创建,系统只以默认的null来充当对象,直到出现下面的代码:

    a=new String(“Hello”);

    这时的对象已通过new关键字被创建(JAVA中几乎所有的对象都要使用new关键字来创建)也许有读者会问对象的名字,恕难奉告,因为对象根本就没有名字,只有内容,大小等诸多属性,还有就是一个或多个可被用来访问对象的引用变量,例如这里的a。

    需要说明,上述针对对象型数据的描述,并不局限于String,同样适用于StringBuffer,类对象引用,接口引用和数组等对象型数据。

    这样,我们终于知道,类Example3中传入方法的x是对象的引用变量而不是对象内容的副本,因为针对String这个对象型数据的内容的访问必须通过调用其引用变量来实现,系统不可能将对象内容直接传入方法。但其结果又为何与类Example2中的显示大相径庭呢?其实根源就在String,String不仅仅是一种对象型数据类型,而且还是一种不可变类型。这里的不可变,指的String引用的对象内容不可变,而不是引用变量本身的引用方向不能变。例如在Example3中,当x将其引用传入方法时,的确使obj引用变量与x引用变量同时引用了对象“Hello ”,但随着代码obj=”JAVA”;的执行,obj将其引用的目标从原来的对象“Hello ”转移至新对象“JAVA”,注意:此时obj并不能去改变自己原来的引用对象“Hello ”本身,只能改变自己的引用方向并引用新对象“JAVA”。(“Hello ”这个对象还存在,只不过现在只剩x变量一个引用了,如果再失去x的引用,例如执行语句:x=null;那么对象“Hello ”就象断了线的风筝,只能等待垃圾回收机制的处理了)这正是“不可变类”真正含义。由此可见,check(String obj)方法的调用,只是改变了obj引用变量的引用关系,而对x引用的对象内容“Hello ”未构成任何影响。

       回过头来再看类Example2,StringBuffer类则是一个可变类,不仅其对象内容可变(使用类的append方法),其引用关系也可变(使用“=”),请读者尝试将代码:

      obj.append(“JAVA”);  改写为:

      obj=new StringBuffer(“JAVA”);想想结果又会是怎样?

        最后的问题,我们需要对上述的知识进行总结和扩展。JAVA中,向一个方法传递简单数据类型时,传入的是副本值,方法的改变不会影响到被传入的变量值;传入对象型数据类型时,传入的是对象引用而不是对象内容,方法的改变绝对不会影响到被传入引用变量的引用关系,但却有可能改变被传入引用变量所引用的对象的内容。请在这里注意String这个不可变类的真正含义。除上述外,向方法传入数组,类对象引用或接口引用得到的结果都是与StringBuffer类的处理相似的。

     看到这里,要用Java解决两个数的交换,看来要把数组封装成类再去操作了.

  • 相关阅读:
    java:找出占用CPU资源最多的那个线程
    vue中的样式穿透
    宽度过小,左右浮动元素会下沉的解决方案
    Object.keys方法之详解
    element UI实现动态生成多级表头
    JavaScript校验身份证,包含省份、长度、出生年月日、校验位的检测、性别、年龄
    JavaScript日期格式化处理
    vue点击编辑按钮,内容变成input可以修改,也可以删除
    NProgress颜色的修改以及在Vue中的使用
    vue中使用raphael.js实现地图绘制
  • 原文地址:https://www.cnblogs.com/xuhn/p/3137742.html
Copyright © 2020-2023  润新知