黑马程序员技术交流社区

标题: 关于引用数据类型 [打印本页]

作者: wyqs92    时间: 2014-5-12 21:27
标题: 关于引用数据类型
本帖最后由 wyqs92 于 2014-5-13 21:33 编辑

老师视频中经常讲到引用数据类型,但是对这个概念有点模糊,求解释!!
作者: skill20    时间: 2014-5-12 21:34
除了八大基本类型以外的基本都是引用数据类型。
作者: 寻找人生目标    时间: 2014-5-12 21:39
除了8大基本数据类型以外  其他都是引用数据类型   例如  类(class)   接口   数组
引用类型数据是指 ,数据类型 在堆内存中创建的数据,而你拿到的是这个数据的引用


作者: 宋健敏    时间: 2014-5-12 21:56
java中的引用数据类型有三种:数组、类、接口。类用new关键字创建一个对象后,对象的具体内容存放在堆内存中,而对象名存放在栈内存中,栈内存中的对象的变量就是堆内存地址的引用。
作者: pandapan    时间: 2014-5-12 22:51
这是我个人的csdn 的博客中所描述的你的内容,咱们可以分享分享。文章标题为《Java 值传递和引用传递(语句拆解理解) 》,我前几天写的第一篇博客,下面把我的博客内容贴出来吧。

Java值传递和引用传递让很多比较纠结,其实在Java中只存在值传递,此时又有人会提出疑问,哪为什么在Java中将一个对象作为方法的参数的时候却可以改变这个对象的属性呢?

这个问题呢,个人感觉还是基本知识的理解不够透彻的原因,下面是我的一些拙见,如果有什么问题呢,还请大家提出来,share and change!

个人觉得有的语句看起来复杂,只要一步一步拆解来看,还是很简单的

第一,咱们先看看貌似和这个问题联系不大的一个基本知识.

一条最基本的java面向对象的语句,

ClassA a = new ClassA();

大家应该知道,这是两个语句的一个简写,即

(1)  ClassA a;

(2) a = new ClassA();

这两句话的基本含义大家应该清楚吧,

最基本的理解是这样的,创建了一个ClassA的对象,并且用a来指向这个对象

再细致一点的话,可以这么说,在内存中开辟了一个空间,这个空间用来放一个新创建的ClassA对象.但是这个对象我怎么操作呢,我得知道这个对象放在哪个地方吧,所以这时就用一个标记把他记下来,方便操作,专业一点的说法呢,我得知道这个对象的内存地址,然后才能对他进行数据的操作.

这时可以看到,第1句话的作用其实就是创建了一个内存地址的值的标记,当让这这是简单的理解方式.

第二,我们再看看类的方法的一些细节知识,比如有下面的一个例子,ClassA的对象作为参数传递给另外一个类ClassB(这其实是错误的说法,个人感觉严格的说法是引用到了另外的一个类的对象)

class ClassB{   
    public void change(ClassA a){
        a.setNo(10);
    }

}

在类ClassB中呢,我们用到了一个ClassA的引用a,为什么说这个不是拿过来a这个对象在操作呢?

其实这个还是语句拆解的问题,整体代码,我们浏览一下


public class Test {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ClassA a;
        a = new ClassA();//为了便于理解,故意拆分
        a.setNo(5);
        ClassB b;
        b = new ClassB();//为了便于理解,故意拆分
        b.change(a);
    }
}
/**
*仅作为简单的被引用的类
*/
class ClassA{
    private int no;
    public int getNo() {
        return no;
    }
    public void setNo(int no) {
        this.no = no;
    }
   
}
/**
* 调用其他的类做演示
*/
class ClassB{   
    public void change(ClassA c){
        c.setNo(10);
    }
}

在上面的这段代码上,我们要看的代码的是主函数的最后一句

b.change(a);

为什么这句话之后,a的no属性就会变成10,而不再是5呢

是这样的,我们也可以拆解这个过程

这个过程可以这样理解的

a呢把自己的引用传给了b的方法的参数c

就是这个意思,

ClassA c = a;

所以呢,c指向的是和a相同的一个内存地址,假如说a指向的是00FF,那么c指向的也是00FF.在传递过程中传递的是这个.

理解了这个道理后,我们便可以理解下面的问题了,假如在ClassB中的change方法中,我改变了参数c指向的地址,我在change方法内部创建了一个新的ClassA对象d,那么a的内容会随之变化吗,大家想想?代码如下

/**
* 调用其他的类做演示
*/
class ClassB{   
    public void change(ClassA c){
        c= new ClassA();
        c.setNo(20);
    }
}

这个便可以理解了,当然是不会的,因为c本来指向的是a所代表的地址00FF,现在我们在操作的是c,把c指向了一个新的ClassA对象,这个内存地址假如说是01FF;那么c所对应的内容改变当然不影响a的内容.

理解了这个,便知道了网上的一种说法,"对象作为参数传递到方法中,其实就是拷贝了一个引用的副本".

说完了这个呢,可能会有人有其他的疑问:

(1)为什么我用基本类型传递,然后在方法中做改变,结果他本身的值没有发生变化呢?

这个我们再说道说道

因为java的基本数据类型和这些类的类型有区别,因为基本类型占用的空间是已知的,并且是简单类型,所以在传递的过程中,直接就把这个值给复制了一份,再进行操作,所以您老人家操作的是复制的那份数据,而不是原来的那个数据

(2) 为什么数组作为参数传递时,改变数组的内容,就有效果呢?大家可以翻翻api文档哈,文档中已经说了,不管是基本类型的数组,还是类的数组,他们的基类是Object,所以呢,他是遵守我们最开始说的,对应引用的传递的规则.
作者: 张盼    时间: 2014-5-12 23:07
数据类型分为基本数据类型和引用数据类型。
基本数据类型有8类:short,byte,char,int,double,long,string,boolean.
除了这8种以外的数据类型都是引用数据类型,比如数组,接口,类

作者: 彭飞    时间: 2014-5-12 23:23
个人觉得,
就刚学习的你,
你现在记清楚:八大基本类型
然后记住:除了八大基本类型以外的基本都是引用数据类型。
比如什么数组啊,String,啊,就够了,
随着深入的学习,你会发现这个问题不再是问题。
不要太牛角尖的思考一些东西。放一放,返回来不攻自破。
作者: 少先队员    时间: 2014-5-13 00:30
除了基本数据类型  剩下的 都是引用数据类型
作者: 张志民    时间: 2014-5-13 23:03
类,接口,和数组都属于引用数据类型,凡是用new类创建的都是引用数据类型,
作者: raikecody    时间: 2014-5-14 12:00
不错,看完回复我也复习了一番




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2