在java中,引用数据不就是一种对象么?为啥在调用函数中不能进行修改数值??

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在java中,引用数据不就是一种对象么?为啥在调用函数中不能进行修改数值??相关的知识,希望对你有一定的参考价值。

我题目中没说清楚,我说的是封装类做参数的时候

楼主语句表达很模糊:
引用数据?(不知道说的是引用数据类型,还是引用某一数据对象)
引用数据类型的数据 ==>是对象;
引用数据==> 不是对象。而是对某对象的引用; 这是一动态过程;

数值?
1. 对象的值==>是内存地址值。即0xaabbcc等; // 这是JVM虚拟机分配的,不能修改值。

2. 对象内部的 成员变量==>存在于堆内存中。 //是可以修改的 (此处不考虑final static的情况)
对象 成员函数的值==>存在于方法区中。 //这只可以调用 (此处不考虑final static的情况)追问

就是调用函数参数是封装类 类型滴啊

追答

类对象作为参数时,是可以修改其指向的引用的。你在所调用的方法里重新new() ,或者赋值为另外一个引用都是可以的

追问

我是说我把封装类类型当做参数,应该是内存地址的引用吧?在调用函数里对其进行操作后,数值改变了吧??然后再主函数中输出,怎么没有改变啊

追答

你把代码发出来,我帮你分析

追问

public class Demo3

public static void main(String[] args)
Integer b = new Integer(6);
plus(b);
System.out.println(b);

public static void plus(Integer a)
a = a+2;
System.out.println(a);



怎么先输出8 在输出6呢 怎么不是全是8啊

追答

1. Integer b = new Integer(6); //在堆内创建了b; b的类型是int
2. plus(b); //此处传递的不是b的内存地址,而是b对应的值.(编译器知道b是普通类型)
3. public static void plus(Integer a) //参数相当于int a;
这个例子就是值传递;

另外说一下: 传地址或传值,实际取决于 数据的存储结构;

参考技术A 你说的是什么意思?以你的补充推测你是指把引用类型作为参数传入方法中并在方法中对他进行修改然后在外面得到修改后的该对象是吧?
如果是这样的话,进行内存分析就很清楚了,先创建一个引用类型的变量,并初始化,会在栈里面创建该引用类型变量,该引用类型变量指向堆里面的一块区域
java函数中传入该引用变量,实际上是在栈里面再创建一个此类型变量,指向相同的堆区,你在函数中如果只单单对该引用类型变量进行改变而不改变其指向的值话,实际上原引用并没有改变,感觉说的比较绕,举例子吧
class Test00

public static void main(String[] args)

int [] a = new int[2];
a[0] = 1;
a[1] = 2;
change(a);
for(int i=0;i<a.length;i++)
System.out.printf(a[i]+" ");

private static void change(int [] b)

int [] c =2,3;
b = c;



最后输出的仍然是1 2,函数中,实际上操作的是拷贝的那个变量,让他指向了和c相同的数组,
可以把b = c改成 b[0] = 2;b[1] = 3;这样就可以了追问

public class Demo3

public static void main(String[] args)
Integer b = new Integer(6);
plus(b);
System.out.println(b);

public static void plus(Integer a)
a = a+2;
System.out.println(a);


这个 瞅瞅

追答

java中函数引用的传参实际上传的是引用地址的拷贝,但他指向的是堆里面的同一内存区,你单纯对对象的操作,比如赋值,只是让它重新指向新的一内存区。

Integer()诸如此类被称为基本数据类型包装类,a是包装类的一个对象,a = a+2,对象怎么能参与算数运算?实际上是因为JDK自从1.5(5.0)版本以后,引入了自动拆装箱的语法,也就是在进行基本数据类型和对应的包装类转换时,系统将自动进行,a = a+2;实际上进行的操作是Integer c = new Integer(a.intValue()+2);
a = c;

看到new没有?对a的赋值,实际上让它指向了c的对象,也就是说让实参的复制指向了另一个堆内存,函数外的b肯定还是指向原来的对象,完全没改变!

由于基本数据类型包装类里面没有表示值的属性,见(api文档)你实际上是不能改变包装类的值的,只能让它指向新的堆内存,所以,你想实现以上代码只能让函数有一个返回值。不知道我说清楚了没有?

参考技术B 应用型数据类型的值是可以在函数中修改的,猜想楼主可能是没有将引用类型初始化,导致出现NullPointer的错误。
在java中分为基本数据类型和引用型数据类型;
基本数据类型包括:boolean,char , byte ,int 等等,这些类型的对象声明的时候,虚拟机就已经为这些类型分配好了相对应的内存空间。
引用型数据类型包括Boolean,Char,Byte,Int这些基本类型的封装类,以及用户自定义的类。当用户声明这些类型的对象时,虚拟机只分配了一个执行该种类型的应用,默认为NULL,需要用户手动调用类的构造函数来生成对象。追问

我已经new了,但是不可以

追答

出现什么错误呢?

追问

不是那个函数传参如果是基本数据类型是对数据的拷贝么?对于引用类型,传递的引用的拷贝(就是地址是吧??)引用型数据类型包括Boolean,Char,Byte,Int这些基本类型的封装类类型在调用函数中进行操作后,为什么在主函数中进行打印的话数值不变?

参考技术C 楼主说的应该是java的参数传递问题,Java 编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用一个副本。指向同一个对象,对象的内容可以在被调用的方法中改变,但对象的引用(不是引用的副本)是永远不会改变的。 参考技术D 因为java中有值传递和地址传递的区别
如果是值传递函数里边修改了 外边是不会变的
如果是地址传递 大家指向的是同一个地址区域 区域内的东西变化了 外边的也当然就变了

java中equals的小问题,不知道为啥,有谁能说说么?

public class yumyu

public static void main(String[] args)
int a=2,b=5;
String ws="123",s="123";
System.out.println(a.equals(s));//报错
System.out.println(s.equals(a));//不报错

System.out.println(a.equals(s));//报错
因为equals是数据对象的方法,而a只是个基本数据类型,它不能调用equals方法!
System.out.println(s.equals(a));//不报错
是因为s能调用equals,而equals的参数是任意的!
参考技术A int换成Integer类型,封装起来,equals()是Object的方法,适用于它所有的子类,可是int 是基本数据类型之一,并不是Object的子类,自JDK1.5开始Integer和int能够自动封装解包 参考技术B s.equals(a)中的equals方法是字符串String的一个方法,只有字符串能用。int型的比较方法是"==",而不是equals。 参考技术C equals是object类中的方法,而object又是Java中所有类的父类,所以所有的类中其实都有equals方法,但是你的那个a就不行了,int是基本数据类型,a根本不是一个类的对象,所以你那样调用当然会报错喽。 参考技术D 你好,a是基本数据类型,不是对象,基本数据类型是不可以调用方法的。而s是String类型的,属于引用数据类型,s作为一个字符串对象,当然可以调用方法啦。 第5个回答  2011-09-13 楼上正解,Cannot invoke equals(String) on the primitive type int!!!

以上是关于在java中,引用数据不就是一种对象么?为啥在调用函数中不能进行修改数值??的主要内容,如果未能解决你的问题,请参考以下文章

DevExpress为啥要安装 直接引用DLL不行么

java编程中基本数据类型是8个,那引用数据类型是接口,数组,String还有啥,有Object么?

为啥java的子类中必须调用父类的构造方法

细说Java揭开Java的main方法神秘的面纱(转)

JAVA里有Shape数据类型么?

C语言数组是“引用类型”么?