精华内容
下载资源
问答
  • 刚刚接触Java时应该听说过一句“万物皆对象”,《Java编程思想》一书中也描述...还有一个问题就是Java是值传递还是引用传递,在C语言中这个问题看到的比较多,在Java中似乎没怎么探讨过。下面围绕上面两个问题来分析!

        刚刚接触Java时应该听说过一句“万物皆对象”,《Java编程思想》一书中也描述对象“将对象视为奇特的变量,它可以存储数据,除此之外,还可以要求它在自身上执行操作。理论上讲,可以抽象待求解问题的任何概念化构件,将其表示为程序中的对象”。对于对象的引用,心里大概知道,却不知怎么表达。还有一个问题就是Java是值传递还是引用传递,在C语言中这个问题看到的比较多,在Java中似乎没怎么探讨过。下面围绕上面两个问题来分析!

     

    *什么是对象引用?

        在C语言中指针是重点亦是难点,到现在还是觉得指针是一个高深的东西,因为它可以直接操作内存,简单地说,指针可以指向一个物理地址,然后操作这一块内存。在Java中的对象的引用和C、C++中的指针是比较像的,不过也只是比较像而已,有人觉得Java中的对象就是一个指针,但事实上,Java中的对象引用和C++中的引用在语法上更加接近,不过两者也存在很大差别。第一版的《Java编程思想》把Java中的对象引用叫做“句柄”,不过我们现在更习惯用“引用”。

         对于Java中的对象引用的解释可以用《Java编程思想》的一段话解释,“每种编程语言都有自己的数据处理方式,有些时候,程序员必须注意将这些要处理的数据是什么类型。你是直接操作元素,还是用某种基于特殊语法的间接表示(例如C/C++里的指针)来操作对象。所有这些在Java中得到了简化,一却都被视为对象。因此,我们可以采用一种统一的语法。尽管一切都被视为对象,但操作的标识符实际是指向一个对象的‘引用’ ”。

    再举一个这本书中有关对象个对象引用的例子:

        对象和对象引用就好比电视机和遥控器,对象是电视机,对象引用是遥控器,即遥控器用来控制电视机,遥控器和电视是关联起来的,我们要控制电视,只需要一个遥控器即可。若有String s; ,这里的s创建了一个字符串引用,就相当于有了一个遥控器,可是没有电视机,可是记得吗,还有万能遥控器,,不过在配对之前,万能遥控器是不与任何一台电视机相关联的,当配对成功之后它就与特定的电视机产生了管理,所以说这个s其实现在还是一个还没有指向任何字符串对象的字符串引用,当我们通过new的方式创建了一个字符串对象,其实就相当于给这个引用关联了一个对象,这个引用关联了一个对象,这个引用就指向了这个对象。

     

    弄清楚了Java中的引用,下面补充一段关于String和StringBuffer的例子:

    public static void main(String[] args) {
        String s1 = new String("hello String!");
        String s2 = s1;
        s2 = "你好 String!";
    
        StringBuffer s3 = new StringBuffer("hello");
        StringBuffer s4 = s3;
        s4.append(" StringBuffer!");
    
        System.out.println("s1: "+s1);   //s1: hello String!
        System.out.println("s2: "+s2);   //s2: 你好 String!
        System.out.println("s3: "+s3);   //s3: hello StringBuffer!
        System.out.println("s4: "+s4);   //s4: hello StringBuffer!
    }
    

    之前总结过:String一旦创建就不会再改变,上述代码中,之前s1和s2指向的是同一个对象,但是当是s2重新赋值的话,所指向的对象就变了,这点对于StringBuffer不同,因为它创建的字符串存在缓冲流,所以s3和s4一开始指向的是同一个对象,然后s4改变了这个对象,这个时候其实s3和s4指向的还是同一个对象,所以内容也是相同的。这里记住一个很重要的知识点——

        如果两个引用指向同一个对象,不管哪个引用去改变这个对象,其结果是对象的内容都会发生改变,而且只有一个对象,但是String是一个特例!

     

    *Java中是值传递还是还是引用传递?

        首先,答案是值传递,属于基础知识,却往往被我们忽视。对于Java中的传递方式必须要深刻理解什么是值,什么是引用,刚好上面我们分析了什么是对象的引用。下面还是来看一个例子:

    public static void main(String[] args) {
            String str = "hello";
            setString(str);
            System.out.println(str);  //hello
        }
        public static void setString(String str) {
            str = str + "String";
        }

        在这个例子中,不要被setString()方法中的str迷惑了,这个str和main方法中的str是不一样的,先不谈值传递和引用传递,我们知道String一旦创建是不可变的,所以这里的str是不会变的。实际上是setString()中的这个str指向了新创建的字符串对象“hello String”。

     

        对于Java中的传参我们可以分为基础类型和引用类型,但两者传参方式都是值传递,对于基础数据类型传参方式是值传递是比较好理解的,重点在于引用类型。还是一个例子:

    Integer a = new Integer(1);
    Integer b = a;
    b++ ;
    System.out.println("a="+a+"\t b="+b);  //a=1	 b=2

        这个例子再次说明Java的引用类型是值传递方式传参的,因为a的值没有随着b的改变同时改变。引用类型中的值传递中“值”指的是什么呢?这里的值其实就是引用所存储的对象的地址值,其实b是a的一个复制品,这个b是独立存在的一个引用,在没有将a复制给它的时候,她还是一个空引用,谁也不指向,但是当a复制给它后,就相当于b存储了和a一样的地址,都指向同一个对象,如图1,但是一旦b自增就相当于Integer b = new Integer(2);,就变成了图2,即b引用的地址就变了。

          所以Java中传参的方式只有一种,那就是值传递,另外,我们知道对于引用都是存在栈中的,而实际的对象是存在堆中的,栈中的引用存放了可以指向实际对象的地址,而引用数据类型的传参,传的就是这个地址!

     

    展开全文
  • java中对象作为参数传递一个方法,到底是值传递,还是引用传递? pdd:所谓java只有按值传递:基本类型 值传递引用类型,地址值传递,所以叫值传递。  当主函数的变量,对象(主本)传递到副函数时,传递的...

    看完绝对清晰~

    java中对象作为参数传递给一个方法,到底是值传递,还是引用传递?

    pdd:所谓java只有按值传递:基本类型  值传递;引用类型,地址值传递,所以叫值传递。

        当主函数的变量,对象(主本)传递到副函数时,传递的变量、对象(方法中的形参)其实都是副本,而副本的改变不会影响主  本。

    基本类型:传递的是值的拷贝,也就是说传递后就互不相关了,也就是说,不过副函数的副本如何变化,主本永远不会被影响。

    引用类型:传递的是引用地址值,有可能会被影响。

    string:具有不可变。是特殊的引用类型,其作用跟基本类型一样,传递后不相关。

     

    原作者:

    String和int参数传递是按值传递还是引用传递?

    一道面试题目,String的传递:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    public String change(String s){

         s = "222";

         return s; 

    }

    public static void main(Stirng[] args){

        String s = "111"

        change(s);

        sout(s);

    }

    我看到题目愣了一下,本来不假思考的结果是111,但仔细想,String是对象类型的,对象传递的是地址,那么地址传递到方法里面后,将指向修改成222,那么结果应该是222才对。实际恰恰相反。

    Java 编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用一个副本。指向同一个对象,对象的内容可以在被调用的方法中改变,但对象的引用(不是引用的副本)是永远不会改变的。 

    java传递参数都是值,如果是对象的话,就是将引用的值复制一份给方法当参数。如果是根据引用把堆里的对象修改了,那么对象真被修改了,不过不是被创建赋值给的那个引用修改的,是方法里的一个复制的引用副本给修改的。换句话说,施瓦星格的媳被施瓦星格的克隆人亲了下。

    用实例去理解,其实这个理解也就是根据jdk的结果告诉我自己记住规则是这样的,以后要记住。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

      public String change(String s, int i, StringBuffer sb, Person p){

            s="123";

            i=3;

            sb.append("woshi");

            p.setAge(100);

            sb = new StringBuffer("sbsb");

            p = new Person("bb",44);

            return s;

        }

     

        @Test

        public void testChange(){

            StringBuffer sb = new StringBuffer("buff");

            String s = "aaa";

            int i = 1;

            Person p = new Person("aa",12);

            i=2;

            change(s,i,sb,p);

    //        s="222";

            System.out.println(s);

            System.out.println(i);

            System.out.println(sb.toString());

            System.out.println(p);

        }

    这里一共测试了String,int,一个对象StringBuffer,一个对象people。让我们来仔细看看这些传递都发生了什么。我想有很大一部分人都猜不出打印结果。

    1

    2

    3

    4

    aaa

    2

    buffwoshi

    Person{id=0, name='aa', age=100, Country=null, hashcode=638783031}

    我们来一个个分析。

    首先是String。

    1

    String s = "aaa";

    这里,jvm创建一个变量引用s,在堆中创建一个对象aaa,将aaa放进常量池。s指向aaa。

    然后就到了change方法里。这里这样理解:将s引用的一个拷贝传给方法change。这样change有一个变量s,这个s也是指向aaa的。那么我们来通过debug来看后来发生了什么。

    1.s指向aaa的时候:

    2.s运行到change方法里的时候

    然后看s再次赋值的时候:

    然后我们运行结束change方法后到主方法里:

    到这里s就结束了。那么如果我们按照传递的是s这个变量的引用,即String s="aaa"中这个s本身,那么,s这个本身是个变量,s指向aaa,在方法change里s又指向了123,回到主方法后s变量的指向被改变了?错!显然s仍旧是aaa,那么只能这样理解:s传递到方法里的时候,复制了s指向的地址给change,change里的s是另一个s,s指向aaa(@718),然后在change中s又指向了123(@731),由于String是不可变类(final and Immutable),这里只是把副本s的指向修改成731,原地址718里的对象没有发生改变因为String不可变。那么,回到主方法的时候,s变量本身没有任何改变,s仍旧指向地址718,718的内容是aaa。所以最终打印aaa。

    然后是StringBuffer

    int是基本类型,所以int只是将值复制一份给别的方法用,这个大家都知道,就不去测试了。现在看StringBuffer发生的改变。

    1.初始化:

    2.到change方法中:

    3.发生append

    4.指向新对象

    这里就要说一下了,副本指向了新对象。就好比,施瓦星格的克隆人找了另一个女的当老婆,而真正的施瓦星格老婆没有变。

    5.回到主方法:

     

    到这里,StringBuffer就结束了。我们必须知道,虽然我们没有去研究源码是怎样实现的,change方法得到是一个sb的副本,只不过这个副本指向708,在change里对708的对象追加,708的对象就真的改变了。然后又把sb副本指向新地址737。这只是把副本指向的地址修改了,如果你在这里打印sb.toString(),打印的就是737里的内容。当跳出change,回到主方法的时候,原sb仍旧还是指向708的,最终就是打印708的结果。和String不同的是,StringBuffer的结果发生了变量,因为StringBuffer是可变的,可以append。而String是不可变的,在change中s=123就是发生两个行为,一个是查找常量池中是否有123,如果没有就在堆中创建123,一个是将s指向123.也就是说这时候是创建了一个新的String对象,而不是把原来的String对象s内容修改。这样,回到主方法的时候,s仍旧是aaa。

    同理,看自己创建的对象people

     

    1.初始化:

    2.p传递到change里的时候

    3.p副本设置age

    4.p副本重新赋值

     这里仍旧要说一下,p副本修改了自己指向,并不影响主方法里的p的指向。主方法里的p的指向没有发生变化,依旧应该还是720.

    5.回到主方法

    总结:

    通过上面对String,StringBuffer,People的研究,应该明白一个道理,重要的话说三遍,重要的规则我都演示了三遍。如果跟着步骤一步步走的,肯定牢记住了:

    java所有的参数传递都是传递的副本,变量所代表的值的副本!java所有的参数传递都是传递的副本,变量所代表的值的副本!java所有的参数传递都是传递的副本,变量所代表的值的副本!

    这里必须记住的就是副本概念。在方法里,运行的时候到这里的线程都会把传过来的参数拷贝副本带自己的工作区中,在工作区中对这个副本的值发生一些改变。最终改变的是副本,如果通过副本的指向修改了指向中的内容,那么那个指向的地址里的内容确实改变了。如果修改了副本的指向,即给副本重新赋值,那么关原来的变量何事?元变量仍旧指向最初的地址。

    那么,String传递过去的是副本,修改了副本的指向,打印元string是不会改变的,因为副本没有能力修改final的String类。

     

    出处:http://blog.csdn.net/zzp_403184692/article/details/8184751

    展开全文
  • 一个对象被当做参数传递一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?  答:是值传递。Java编程语言中只有由值传递参数的。当一个对象实例作为一个...

      当一个对象被当做参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

        答:是值传递。Java编程语言中只有由值传递参数的。当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用。对象的内容可以在被调用的方法中改变,但对象的引用是永远不会改变的。

    展开全文
  • java中的参数传递(只有值传递没有引用传递

    万次阅读 多人点赞 2019-07-31 19:25:14
    Java中只有传值调用(值传递),没有传址调用(址传递或者引用传递)。所以在java方法中改变参数的值是不会改变原变量的值的,但为什么改变引用变量的属性值却可以呢?请看下面的解答。 java中的数据类型 Java中...

    Java中只有传值调用(值传递),没有传址调用(址传递或者引用传递)。所以在java方法中改变参数的值是不会改变原变量的值的,但为什么改变引用变量的属性值却可以呢?请看下面的解答。

    java中的数据类型

    Java中数据类型分为两大类:基本类型和引用类型。相应的,变量也分这两种类型:基本类型和引用类型。

    基本类型的变量保存原始值,即它代表的值就是数值本身;

    而引用类型的变量保存的值是引用值,"引用值"指向内存空间的地址,代表了某个对象的引用,而不是对象本身,对象本身存放在这个引用值所表示的地址的位置。

    基本类型包括:byte,short,int,long,char,float,double,Boolean,returnAddress。

    引用类型包括:类、接口类型和数组。

    java中只有值传递

    在日常编码中,会经常看到如下现象:

    1、对于基本类型参数,在方法体内对参数进行重新赋值,不会改变原有变量的值。

    2、对于引用类型参数,在方法体内对参数进行重新赋予引用,不会改变原有变量所持有的引用。

    3、方法体内对参数进行运算,不会改变原有变量的值。

    4、对于引用类型参数,方法体内对参数所指向对象的属性进行操作,将改变原有变量所指向对象的属性值。

    举个例子:

    public class Main {
    
        private static void getMiddleOne(boolean b, Boolean boo, Boolean[] arr){
    
            b = true;
    
            boo = new Boolean(true);
    
            arr[0] = true;
    
        }
    
           //测试
    
        public static void main(String[] args) {
    
            boolean b = false;
    
            Boolean boo = new Boolean(false);
    
            Boolean[] arr = new Boolean[]{false};
    
            getMiddleOne(b, boo, arr);
    
            System.out.println(b);
    
            System.out.println(boo.toString());
    
            System.out.println(arr[0]);
    
            /**
    
            * output:
    
            * false
    
            * false
    
            * true
    
            */
    
        }
    
    }

    我们只要了解了下面两点就可以解答上面的现象了:

    1、基本数据类型的值就是数值本身,所以示例中的b的值就是false;包装类因为会自动装箱拆箱,所以可以和基本类型一样处理,所以示例中boo的值就是false;数组是引用类型,所以arr的值就是指向该Boolean[]的引用。

    2、java中只有值传递没有引用传递,所以传入getMiddleOne方法的三个参数分别是b的值拷贝, boo的值拷贝, arr的值拷贝。

    通过上面两点就可以清楚了,getMiddleOne方法中执行的 b=true 和 boo = new Boolean(true) 都是把新值赋给了他们的拷贝,所以不改变原变量的值;同样,arr[0] = true 是把true复制给了arr的拷贝所指向的数组的第一个元素,arr的值和arr的拷贝的值都是该数组的引用,所以arr的拷贝所指向的数组和arr所指向的数组是同一个,所以改变arr的拷贝的数组的元素会同样影响到原变量arr。

    总结

    java中只有值传递,基本类型传递的是值的副本,引用类型传递的是引用的副本。

     

    展开全文
  • 一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象引用对象的属性可以在被调用过程中被改变,但对对象引用的改变是不会影响到调用者的。C++和C#中可以通过传引用或传输出参数来改变传入...
  • Java中对象对象引用、堆、栈、值传递以及引用传递的详细解释 ...一个对象可以被多个引用所指向。 (2).对象引用: 类似于C++中的地址。通过对象引用可以找到对象一个引用可以指向多个对象。操纵
  • Java对象对象引用,参数传递

    千次阅读 2018-07-01 19:45:46
    在Java中,万物皆对象!...比如定义一个学生类 public class Student { private int id; private String name; private int age; public Student() { // TODO Auto-generated constructor stub su...
  • c#中对象作为方法参数传递引用传递,值传递这本是一个很简单的知识点,但是我们在实际开发过程中还是蛮容易踩到这个 坑,尤其是在维护他人代码。逻辑比较复杂的时候,容易出错,哈哈,警醒一下。 如图所示,对象...
  • Java方法传递参数是值传递,但是在传递对象引用的时候,引用的值就是对象实际在堆内存的地址
  • 其实java函数中的参数都是传递值的,所不同的是对于基本数据类型传递的是参数的份拷贝,对于类类型传递的是该类参数的引用的拷贝,当在函数体中修改参数值时,无论是基本类型的参数还是引用类型的参数,修改的只是...
  • 内容导航前言代码测试总结测试源码 前言 最近写了挺长一段时间的Lua,...虽说把一个函数来回设置方便了许多,但是同样带来了一些不容易发现的问题,如果搞不清定义域和引用关系,常常会导致程序错误,比如最近用...
  • 但是字符串作为一个对象传递却意外的是值传递。 先定义值传递意义:就是讲原先的基本变量或者引用拷贝一份,作为参数传递给函数。特点是当函数里面对该基本变量做修改后只对副本起作用,对原先的基本变量或者引用...
  • 一个对象被当作参数传递一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递 答:是值传递。Java 编程语言只有值传递参数。当一个对象实例作为一个参数被传递...
  • 对象和数组在赋值的时候都是引用传递,赋值的时候只是传递一个指针。
  • 关于Java对象作为参数传递是传值还是传引用的问题

    万次阅读 多人点赞 2016-09-06 22:37:20
    前言 在Java中,当对象作为参数传递时,究竟传递的是对象的值,还是对象引用,这是一个饱受争议的话题。若传的是值,那么函数接收的只是实参的一个副本,函数对形参的操作并不会对实参产生影响;若传的是引用,...
  • 背景: 做项目的时候,将一个对象引用传入到方法中,期待方法里面创建一个新的对象给这个引用,后面就可以拿着这个对象用了。  可结果就是,定义在外面的对象引用并没有拿到这个引用 demo.java ...
  • 是值传递。Java 编程语言只由值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象引用对象的内容可以在被调用的方法中改变,但对象引用是永远不会改变的。
  • python参数传递对象引用

    千次阅读 2018-06-08 10:04:56
    大家都知道在python中,一切皆对象,变量也不再具有类型,变量仅仅是对象一个引用,我们通常用变量来测类型,通常测得就是被这个变量引用对象的类型。 例如: 这里的类型就是123这个对象的类型。变量的作用...
  • 传递引用传递

    千次阅读 2018-09-20 21:35:45
    一个对象被当作参数传递一个方法后,此方法可改变这个对象的属性,并 可返回变化后的结果,那么这里到底是值传递还是引用传递? 解答:值传递。 值传递引用传递的区别: 值传递对象发送改变 不会对引用的内存...
  • 在 PHP5 中,如果按引用传递,就是将 zval 的地址赋给另一个变量,这时,两个变量都同时指向一个 zval 。而按值传递则是复制一个 zval,两个变量指向两个不同的 zval 。(为了简化,这里忽略 copy on write)按引用...
  • php数组和对象的值传递引用传递

    千次阅读 2012-12-13 16:46:26
    一般的数据类型(int, ...这里详细介绍一下数组和的类的对象作为参数进行值传递的区别 数组值传递 实例代码: ?   function main() {  $cc = array(  'a','b'  );
  • Java函数传递对象与C++传递引用

    千次阅读 2010-12-15 13:42:00
    我听说过这么句话,“Java函数传参都是传递引用。”,貌似还很流行。不知道是不是Java没有指针概念的缘故,总之如果你学过C++,那就要记住,Java对象在函数间的传递不同于C++概念中的传递引用,如果不懂C++,无视...
  • 文章目录1 类与对象的概念2 类与对象的定义与使用2.1 类的定义2.2 对象的定义2.3 对象内存分析2.4 引用传递分析 1 类与对象的概念   类是一个共性的概念,而对象一个具体的,可以使用的事物。   类是生产...
  • 我们知道Java数据类型基本分为两种,是基本类型,还种是引用类型。 基本类型: 对象类型是固定的,如下: byte,short,int,long,float,double,char,boolean 并且被创建后的值是存放在内存
  • 先贴篇博文,非常形象的解释了对象对象引用间的关系 .Java语言中通过对象引用来操纵对象,要注意的一点是对象对象引用是存储在不同的地方的,因为对象往往所占的空间要求比较大,所以对象存储在堆中,而...
  • 问:当一个对象被当做参数传递一个方法后,此方法可改变这个对象的属性,并返回变化后的结果,那么这里到底是值传递还是引用传递? 答:是值传递。在java语言中只有值传递参数;当一个对象实例作为一个参数被...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 643,700
精华内容 257,480
关键字:

向一个对象传递一个引用