首页编程java编程什么java 引用类型 Java里什么是引用类型

什么java 引用类型 Java里什么是引用类型

编程之家2023-10-11102次浏览

各位老铁们好,相信很多人对什么java 引用类型都不是特别的了解,因此呢,今天就来为大家分享下关于什么java 引用类型以及Java里什么是引用类型的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看看吧!

什么java 引用类型 Java里什么是引用类型

Java里什么是引用类型

最简答来说除了8中基本类型以外剩下的都是引用类型

Java提供两种不同的类型:引用类型和原始类型(或内置类型)。Int是java的原始数据类型,Integer是java为int提供的封装类。Java为每个原始类型提供了封装类。

原始类型封装类

什么java 引用类型 Java里什么是引用类型

boolean-->Boolean

char--->Character

byte-->Byte

什么java 引用类型 Java里什么是引用类型

short-->Short

int-->Integer

long-->Long

float-->Float

double-->Double

引用类型和原始类型的行为完全不同,并且它们具有不同的语义。引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始类型实例变量的缺省值与它们的类型有关。同时为了面向对象操作的一致性,这些基本类型都有相应的封装类型:Integer、Short、Long、Byte、Float、Double、Character等。

因为封装类型是对象,所以可以进行相应的很多对象能力函数操作,这样就可以提供很多基本类型难以完成的工作的完成和实现。

你可以通过以下方式来声明该类型。

int a,a为int类型的变量

char a,a为char类型的

String对象

1.首先String不属于8种基本数据类型,String是一个对象。

因为对象的默认值是null,所以String的默认值也是null;但它又是一种特殊的对象,有其它对象没有的一些特性。

2. new String()和new String(“”)都是申明一个新的空字符串,是空串不是null;

3. String str=”punkll”;

String str=new String(“punkll”);的区别:

在这里,我们不谈堆,也不谈栈,只先简单引入常量池这个简单的概念。

常量池(constant pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口等中的常量,也包括字符串常量。

看例1:

String s0=”punkll”;

String s1=”punkll”;

String s2=”punk”+“ll”;

System.out.println( s0==s1);

System.out.println( s0==s2);

结果为:

true

true

首先,我们要知结果为道Java会确保一个字符串常量只有一个拷贝。

因为例子中的s0和s1中的”punkll”都是字符串常量,它们在编译期就被确定了,所以s0==s1为true;而”punk”和”ll”也都是字符串常量,当一个字符串由多个字符串常量连接而成时,它自己肯定也是字符串常量,所以s2也同样在编译期就被解析为一个字符串常量,所以s2也是常量池中”punkll”的一个引用。

所以我们得出s0==s1==s2;

用new String()创建的字符串不是常量,不能在编译期就确定,所以new String()创建的字符串不放入常量池中,它们有自己的地址空间。

看例2:

String s0=”punkll”;

String s1=new String(”punkll”);

String s2=”punk”+ new String(“ll”);

System.out.println( s0==s1);

System.out.println( s0==s2);

System.out.println( s1==s2);

结果为:

false

false

false

例2中s0还是常量池中”punkll”的应用,s1因为无法在编译期确定,所以是运行时创建的新对象”punkll”的引用,s2因为有后半部分new String(“ll”)所以也无法在编译期确定,所以也是一个新创建对象”punkll”的应用;明白了这些也就知道为何得出此结果了。

关于Java引用类型变量

基本数据类类型存的是数值本身,而引用类型变量在内存放的是数据的引用,并不是数据的本身,引用类型变量是以间接方式去获取数据。引用类型变量都属于对象类型,如:数组、类、字符串等都属于引用类型变量。所以,引用类型变量里面存放的是数据的地址。

说白了基本数据类型变量就像是直接放在柜子里的东西,而引用数据类型变量就是这个柜子对应编码的钥匙。钥匙号和柜子对应。

java三个引用类型

四种引用类型

所以在 JDK.1.2之后,Java对引用的概念进行了扩充,将引用分为了:强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)4种,这 4种引用的强度依次减弱。

一,强引用

Java中默认声明的就是强引用,比如:

Object obj= new Object();//只要obj还指向Object对象,Object对象就不会被回收

obj= null;//手动置null

只要强引用存在,垃圾回收器将永远不会回收被引用的对象,哪怕内存不足时,JVM也会直接抛出OutOfMemoryError,不会去回收。如果想中断强引用与对象之间的联系,可以显示的将强引用赋值为null,这样一来,JVM就可以适时的回收对象了

二,软引用

软引用是用来描述一些非必需但仍有用的对象。在内存足够的时候,软引用对象不会被回收,只有在内存不足时,系统则会回收软引用对象,如果回收了软引用对象之后仍然没有足够的内存,才会抛出内存溢出异常。这种特性常常被用来实现缓存技术,比如网页缓存,图片缓存等。

在 JDK1.2之后,用java.lang.ref.SoftReference类来表示软引用。

下面以一个例子来进一步说明强引用和软引用的区别:

在运行下面的Java代码之前,需要先配置参数-Xms2M-Xmx3M,将 JVM的初始内存设为2M,最大可用内存为 3M。

首先先来测试一下强引用,在限制了 JVM内存的前提下,下面的代码运行正常

public class TestOOM{

public static void main(String[] args){

testStrongReference();

}

private static void testStrongReference(){

//当 new byte为 1M时,程序运行正常

byte[] buff= new byte[1024* 1024* 1];

}

}

但是如果我们将

byte[] buff= new byte[1024* 1024* 1];

替换为创建一个大小为 2M的字节数组

byte[] buff= new byte[1024* 1024* 2];

则内存不够使用,程序直接报错,强引用并不会被回收

接着来看一下软引用会有什么不一样,在下面的示例中连续创建了 10个大小为 1M的字节数组,并赋值给了软引用,然后循环遍历将这些对象打印出来。

public class TestOOM{

private static List<Object> list= new ArrayList<>();

public static void main(String[] args){

testSoftReference();

}

private static void testSoftReference(){

for(int i= 0; i< 10; i++){

byte[] buff= new byte[1024* 1024];

SoftReference<byte[]> sr= new SoftReference<>(buff);

list.add(sr);

}

System.gc();//主动通知垃圾回收

for(int i=0; i< list.size(); i++){

Object obj=((SoftReference) list.get(i)).get();

System.out.println(obj);

}

}

}

打印结果:

我们发现无论循环创建多少个软引用对象,打印结果总是只有最后一个对象被保留,其他的obj全都被置空回收了。

这里就说明了在内存不足的情况下,软引用将会被自动回收。

值得注意的一点,即使有 byte[] buff引用指向对象,且 buff是一个strong reference,但是 SoftReference sr指向的对象仍然被回收了,这是因为Java的编译器发现了在之后的代码中, buff已经没有被使用了,所以自动进行了优化。

如果我们将上面示例稍微修改一下:

private static void testSoftReference(){

byte[] buff= null;

for(int i= 0; i< 10; i++){

buff= new byte[1024* 1024];

SoftReference<byte[]> sr= new SoftReference<>(buff);

list.add(sr);

}

System.gc();//主动通知垃圾回收

for(int i=0; i< list.size(); i++){

Object obj=((SoftReference) list.get(i)).get();

System.out.println(obj);

}

System.out.println("buff:"+ buff.toString());

}

则 buff会因为强引用的存在,而无法被垃圾回收,从而抛出OOM的错误。

如果一个对象惟一剩下的引用是软引用,那么该对象是软可及的(softly reachable)。垃圾收集器并不像其收集弱可及的对象一样尽量地收集软可及的对象,相反,它只在真正“需要”内存时才收集软可及的对象。

三,弱引用

弱引用的引用强度比软引用要更弱一些,无论内存是否足够,只要 JVM开始进行垃圾回收,那些被弱引用关联的对象都会被回收。在 JDK1.2之后,用 java.lang.ref.WeakReference来表示弱引用。

我们以与软引用同样的方式来测试一下弱引用:

private static void testWeakReference(){

for(int i= 0; i< 10; i++){

byte[] buff= new byte[1024* 1024];

WeakReference<byte[]> sr= new WeakReference<>(buff);

list.add(sr);

}

System.gc();//主动通知垃圾回收

for(int i=0; i< list.size(); i++){

Object obj=((WeakReference) list.get(i)).get();

System.out.println(obj);

}

}

打印结果:

可以发现所有被弱引用关联的对象都被垃圾回收了。

四,虚引用

虚引用是最弱的一种引用关系,如果一个对象仅持有虚引用,那么它就和没有任何引用一样,它随时可能会被回收,在 JDK1.2之后,用 PhantomReference类来表示,通过查看这个类的源码,发现它只有一个构造函数和一个 get()方法,而且它的 get()方法仅仅是返回一个null,也就是说将永远无法通过虚引用来获取对象,虚引用必须要和 ReferenceQueue引用队列一起使用。

public class PhantomReference<T> extends Reference<T>{

/**

* Returns this reference object's referent. Because the referent of a

* phantom reference is always inaccessible, this method always returns

*<code>null</code>.

*

*@return<code>null</code>

*/

public T get(){

return null;

}

public PhantomReference(T referent, ReferenceQueue<? super T> q){

super(referent, q);

}

}

那么传入它的构造方法中的 ReferenceQueue又是如何使用的呢?

五,引用队列(ReferenceQueue)

引用队列可以与软引用、弱引用以及虚引用一起配合使用,当垃圾回收器准备回收一个对象时,如果发现它还有引用,那么就会在回收对象之前,把这个引用加入到与之关联的引用队列中去。程序可以通过判断引用队列中是否已经加入了引用,来判断被引用的对象是否将要被垃圾回收,这样就可以在对象被回收之前采取一些必要的措施。

文章到此结束,如果本次分享的什么java 引用类型和Java里什么是引用类型的问题解决了您的问题,那么我们由衷的感到高兴!

java中字符是什么(java中String是什么)ifsum ifsumif函数的使用方法