java 判断一个对象是值类型还是引用类型
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 判断一个对象是值类型还是引用类型相关的知识,希望对你有一定的参考价值。
1、 JAVA中值类型和引用类型的不同?[定义]
引用类型表示你操作的数据是同一个,也就是说当你传一个参数给另一个方法时,你在另一个方法中改变这个变量的值,
那么调用这个方法是传入的变量的值也将改变.值类型表示复制一个当前变量传给方法,
当你在这个方法中改变这个变量的值时,最初生命的变量的值不会变.通俗说法: 值类型就是现金,要用直接用;引用类型是存折,要用还得先去银行取现。----(摘自网上)
[值类型]
也就是基本数据类型 基本数据类型常被称为四类八种
四类:
1,整型 2,浮点型 3,字符型4,逻辑型
八种:
1,整型3种 byte,short,int,long
2,浮点型2种 float,double
3,字符型1种 char
4,逻辑型1种 boolean
[引用类型]
除了四类八种基本类型外,所有的类型都称为引用类型(数组,类,接口,字符串)
在弄清楚值类型与引用类型之后,最后一点就是值传递与引用传递,这才是关键
[值传递]
基本数据类型赋值都属于值传递,值传递传递的是实实在在的变量值,是传递原参数的拷贝,值传递后,实参传递给形参的值,形参发生改变而不影响实参。
[引用传递]
引用类型之间赋值属于引用传递。引用传递传递的是对象的引用地址,也就是它的本身(自己最通俗的理解)。
引用传递:传的是地址,就是将实参的地址传递给形参,形参改变了,实参当然被改变了,因为他们指向相同的地址。
引用和我们的指针差不多,但是它不又不需要我们去具体的操作
[内存分配]
一个具有值类型(value type)的数据存放在栈内的一个变量中。即是在栈中分配内存空间,直接存储所包含的值,其值就代表数据本身。
值类型的数据具有较快的存取速度。
一个具有引用类型(reference type)的数据并不驻留在栈中,而是存储于堆中。即是在堆中分配内存空间,不直接存储所包含的值,而是指向所要存储的值,其值代表的是所指向的地址。当访问一个具有引用类型的数据时,需要到栈中检查变量的内容,该变量引用堆中的一个实际数据。引用类型的数据比值类型的数据具有更大的存储规模和较低的访问速度。
Java中有垃圾回收机制,栈内存中的变量随着方法的结束内存自然销毁了,而用引用类型的时候,当方法结束的时候,这个对象可能被另一个引用类型所应用,不会销毁,只有当一个对象没有任何引用变量引用的时候,垃圾回收机制才会回收 参考技术A return obj.getClass.isPrimitive();
https://www.cnblogs.com/ninth/p/6164471.html 参考技术B 用typeof(object) 参考技术C var改成object,判断类型用typeof()==int或者你要的类型即可
java里String类型可以直接赋值,保存的是值还是引用的地址?
比如String a="你好"
a地址里保存的就是“你好”,还是保存的是“你好”的一个地址?而真正的“你好”值,在常量池里的某一个地址里保存?
String a=“你好”也是直接赋值 那和 int b=3;这个直接赋值 有什么区别?
为什么引用类型 一定要用地址引用下,不能像基本数据类型一样 直接赋值多省事?为什么还要保存个地址,然后在指向对象,不是很麻烦吗?
第二个问题,String和int直接赋值的区别。首先,最大的区别,一个是对象,一个是数值,对象可以为null,数值却必须有值,哪怕你没赋值,系统也会自动赋值为0。int b = 3是直接在内存空间分配了一块空间b内容是3,b的内容是可变的,可以变为5,6……而String对象是不可变的,“你好”实际是在堆中存在的,把引用给了a,如果String a = "bbb"则是把另一个新的对象"bbb"的地址引用给了a,之前的对象“你好”是没有改变的。
第三个问题,为什么引用类型赋值不能像基本数据类型呢?因为引用类型远比基本数据类型复杂啊,基本数据类型只有数值、字符、布尔三种数据类型,可以很简单得表示出来,像2、'a'、true这样,赋值也自然容易,但是引用类型就不一样了,可能要引用的类型是个人,或者是一个职业,这样复杂的东西都是同时包含好多不同属性的,这总不能直接用一个数值就能表示吧,所以要想找它的话只能找它的地址了,然后再根据地址找到对应的对象,虽然麻烦一些,但是也无法避免。
好了,希望我的回答能够对你有所帮助。追问
说的挺好的,对我很有帮助,还有点没明白,在问问,我个人理解是这样的,int a=3,因为是基本类型,不是引用类型,所以3没有常量池,在编译成class文件后,就变成32位的二进制3,此时在硬盘里躺着,当运行class文件时候,在内存开辟一个叫a的空间,然后直接把32位的3放进去,完成基本类型的赋值,这是我对基本类型赋值的理解,而且这也符合你说的保存的是值而不是引用地址!这个理解对吗?
追答你的理解有一点问题,简单数据类型都是直接存储在内存中的内存栈上的,数据本身的值就是存储在栈空间里面,而java语言里面只有这八种数据类型这种存储模型,引用则是存储在有序的内存栈上的,而对象本身的值存储在内存堆上的,它们都是在内存中,只是在内存的不同区域,本质上也都是二进制的,不会在硬盘中出现。
追问那我问你class文件如果不运行,是不是在硬盘上保存的?那里面都是编译后的二进制,不在硬盘上保存,你放哪保存?肯定是运行时候,从硬盘上加载文件到内存啊 所有程序都这么运行啊
对了,你说的栈是运行以后在真实内存上的栈内存吗?那class文件里有没有栈的说法?
class文件肯定是要存放在硬盘的,这个你说的没错,我刚才说的是运行起来以后的存放位置,class里没有栈,都是在计算机真实内存中的堆和栈等等。
追问那就对了,那就从运行class文件开始说,运行时候,你的3从哪里来,是不是肯定先在编译后的class文件里啊,而且还是32位的二进制3,运行的时候才是你说的,在计算机真实内存中的栈里开辟一个叫a的空间,然后把32位的二进制3放进去,我这么理解一点错也没有啊?你怎么说我我理解的有问题 咱先把这个搞明白,引用的就好理解了
追答不好意思,是我理解错了你的意思,你说的是在运行之前的东西,那这么理解的话是可以的,在运行以前class里所有的东西对于计算机来说都是一样的,全都是在硬盘中,然后在运行后再根据不同内容才有所区分,然后才是刚才说到的内存的东西。
追问听说栈内存的数据可以共享,比如int a=3;int b=3 ,b它是怎么个共享3?基本类型也不是引用,不可能指向地址的,难道说b指向的是a?那不就变成b保存的是a的地址了吗?那就不对了,那岂不是成引用类型了,搞不懂咋回事了
追答同志,干脆你加我qq跟你说吧,这么说太费劲了410782240
参考技术A 先给你一个在博客园看到的说明问题1
我声明了什么!
String s = "Hello world!";
许多人都做过这样的事情,但是,我们到底声明了什么?回答通常是:一个String,内容是“Hello world!”。这样模糊的回答通常是概念不清的根源。如果要准确的回答,一半的人大概会回答错误。
这个语句声明的是一个指向对象的引用,名为“s”,可以指向类型为String的任何对象,目前指向"Hello world!"这个String类型的对象。这就是真正发生的事情。我们并没有声明一个String对象,我们只是声明了一个只能指向String对象的引用变量。所以,如果在刚才那句语句后面,如果再运行一句:
String string = s;
我们是声明了另外一个只能指向String对象的引用,名为string,并没有第二个对象产生,string还是指向原来那个对象,也就是,和s指向同一个对象。
我的理解:字符串的底层真实实现,还是和C一样,用的数组来存储多个char类型的字符,所以可以理解成声明一个数组,因为数组是多个内存地址的集合,你想想,那么多地址,如果是直接赋值,该存哪个地址哇?暂时这么多,还要需要欢迎提问 参考技术B String 是属于引用类型,是地址操作。
int 是基本数据类型,可以直接赋值,而Integer是包装类,也是引用类型,Integer i = null;说白了,Integer就是一个引用,可以指向null。而int必须赋数字。
//String 这个东西:
String a="你好"; a是地址不假,但是地址指向的不是中文的你好,而是编码转换的。。
//比如:System.out.println((char)20320); 20320就表示“你”,而不是直接保存的汉字。 参考技术C 像这种的变量的话,String a 定义的是一个引用,而“你好”是保存在方法区,有一个地址,而那个a呢,则是在内存 栈区中分配了一个地址,但是里面的数据则是“你好”的地址,基本数据类型的话,像int a=0;的话,直接放入到内存 栈区 参考技术D String是String类,Integer也是类
int是数据类型
Integer b=3;
和
int b=3;
还是有区别的
以上是关于java 判断一个对象是值类型还是引用类型的主要内容,如果未能解决你的问题,请参考以下文章