java中的引用类型概念

转自:http://blog.sina.com.cn/s/[email protected]陌上蜗牛

1、什么是引用类型


   
引用类型(reference type)指向一个对象,不是原始值,指向对象的变量是引用变量。

在java里面除去基本数据类型的其它类型都是引用数据类型,自己定义的class类都是引用类型,可以像基本类型一样使用。

   

示例如下:

    public class
MyDate {
       
private int day = 8;
       
private int month = 8;
       
private int year = 2008;
       
private MyDate(int day, int month, int year){...}
       
public void print(){...}
    }
    public class
TestMyDate {
       
public static void main(String args[]) {
       
    //这个today变量就是一个引用类型的变量
     
      MyDate
today = new MyDate(23, 7, 2008);
       
}
    }

2、引用类型的赋值


在java编程语言中,用类的一个类型声明的变量被指定为引用类型,这是因为它正在引用一个非原始类型,这对赋值具有重要的意义。如下代码:

int x =
7;
    int y =
x;
    String s =
"Hello";
    String t =
s;

四个变量被创建:两个原始类型 int
和两个引用类型String。x的值是7,而这个值被复制到y;x和y是两个独立的变量且其中任何一个的进一步的变化都不对另外一个构成影响。至于变量s和t,只有一个String对象存在,它包含了文本"Hello",s和t均引用这个单一个对象。

如果将变量t重新定义为t="World";则新的对象World被创建,而t引用这个对象。

3、按值传递和按引用传递的区别

   
1)按值传递
   
   
指的是在方法调用时,传递的参数是按值的拷贝传递。示例如下:

1.    public class TempTest
{
2.
      
private void test1(int a) {
3.
          
// 做点事情
4.
          
a++;
5.
      
}
6.

7.
      
public static void main(String args[]) {
8.
          
TempTest t = new TempTest();
9.
          
int a = 3;
10.
          
t.test1(a);//这里传递的参数a就是按值传递。
11.
          
System.out.printIn("main方法中的a===" + a);
12.
       
}
13.     }
   
   
按值传递的重要特点:传递的是值的拷贝,也就是说传递后就互不相关了。第9行的a和第2行的a是两个变量,当改变第2行的a的值,第9行a的值是不变的,所以打印结果是3。

main  方法中的a 为 3
    test1 方法中的a
为 4
   
   
我们把第9行的a称之为实参,第2行的a称之为形参;对于基本数据类型,形参数据的改变,不影响实参的数据。

2)按引用传递

指的是在方法调用时,传递的参数是按引用进行传递,其实传递的是引用的地址,也就是变量所对应的内存空间的地址。

示例如下:

1.    public class TempTest
{
2.
      
private void test1(A a) {
3.
          
a.age = 20;
4.
          
System.out.printIn("test1方法中的age="+a.age);
5.
      
}
6.
      
public static void main(String args[]) {
7.
          
TempTest t = new TempTest();
8.
          
A a = new A();
9.
          
a.age = 10;
10.
         
t.test1(a);// 这里传递的参数a就是按引用传递
11.
            
System.out.printIn("main方法中的age="+a.age);
12.
       
}
13.     }
14.     classA {
15.        
public int age = 0;
16.    
}

   
运行结果如下:test1方法中的age = 20  main方法中的age = 20

按引用传递的重要特点:

传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间)。

要想正确理解按引用传递的过程,就必须学会理解内存分配的过程,内存分配示意图可以辅助我们去理解这个过程。

用上面的例子来进行分析:
  
   
(1)、运行开始,运行第8行,创建了一个A的实例,内存分配示意图如下:

main方法中的a 
   
     

(2)、运行第9行,修改了A实例里面的age的值,内存分配示意图如下:

main方法中的a 
     


 
   
(3)、运行第10行,是把main方法中的变量a所引用的内存空间地址,按引用传递给test1方法中的a变量。请注意:这两个a变量是完全不同的,不要被名称相同所蒙蔽,但它们指向了同一个A实例。内存分配示意图如下:

(4)、运行第3行,为test1方法中的变量a指向A实例的age进行赋值,完成后形成新的内存示意图如下:


    
此时A实例的age值的变化是由test1方法引起的。
   
   
(5)、运行第4行,根据此时的内存示意图,输出test1方法中的age=20

(6)、运行第11行,根据此时的内存示意图,输出main方法中的age=20

3)对上述例子的改变

   
理解了上面的例子,可能有人会问,那么能不能让按照引用传递的值,相互不影响呢?就是test1方法里面的修改不影响到main方法里面的呢?

方法是在test1方法里面新new一个实例就可以了。改变成下面的例子,其中第3行为新加的:

1.    public class TempTest
{
2.
      
private void test1(A a) {
3.
          
a = new A();// 新加的一行
4.
          
a.age = 20;
5.
          
System.out.printIn("test1方法中的age="+a.age);
6.
      
}
7.
      
public static void main(String args[]) {
8.
          
TempTest t = new TempTest();
9.
          
A a = new A();
10.
          
a.age = 10;
11.
         
t.test1(a);// 这里传递的参数a就是按引用传递
12.
            
System.out.printIn("main方法中的age="+a.age);
13.
       
}
14.     }
15.     classA {
16.        
public int age = 0;
17.    
}

运行结果为:test1方法中的age=20  main方法中的age=10

实现了按引用传递的值传递前与传递后互不影响,还是使用内存示意图来理解一下:

(1)、运行开始,运行第9行,创建了一个A实例,内存分配示意图如下:


   
   
(2)、运行第10行,是修改A实例里面的age的值,运行后内存分配示意图如下:


   
   
(3)、运行第11行,是把mian方法中的变量a所引用的内存地址,按引用传递给test1方法中的a变量。请注意:这两个a变量是完全不同的,不要被名称相同所蒙蔽。

(4)、运行第3行,为test1方法中的变量a重新生成了新的A实例,完成后形成的新的内存示意图如下:

(5)、运行第4行,为test1方法中的变量a指向的新的A实例的age进行赋值,完成后形成新的内存示意图如下:

注意:这个时候test1方法中的变量a的age被改变,而main方法中的a变量是没有改变的。

(6)、运行第5行,根据此时的内存示意图,输出test1方法中的age=20

(7)、运行第12行,根据此时的内存示意图,输出main方法中的age=10

说明:

(1)、“在Java里面参数传递都是按值传递”这句话的意思是:按值传递是传递的值的拷贝,按引用传递其实传递的是引用的地址值,所以统称按值传递。

(2)、在Java里面只有基本类型和按照下面这种定义方式的String是按值传递,其它的都是按引用传递。就是直接使用双引号定义的字符串方式:String
str = "Java快车";

java中的引用类型概念,布布扣,bubuko.com

时间: 2024-11-29 04:17:01

java中的引用类型概念的相关文章

Java 中的引用类型

Java 中的引用类型? 除了8大基本数据类型(不包括void),其他都是引用类型. 可能面试官就是问的上面这个,但是如果你能补充下去,这会是一个很好的展现机会! java中的引用类型分为4种:强,软,弱,虚!这中分类与GC有关,如果你对GC有一些了解的话,可以继续谈谈,如果不了解GC的话,建议适可而止.. 1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序才能使用它.

java 中包的概念,常量,静态与继承

一.包的概念:创建,使用. 1.新建包: 最上面一行,之前不能再有其它代码了. package 包名; 注意:包名一般都有命名的规范.例如:com.itnba.maya.zy(从大到小). 2.使用包: import 包名.*; import 包名.类名; 例如:import com.itnba.maya.zy.*; 注意:import不要放在package的上面上 package com.itnba.maya.zy; import com.itnba.maya.zyy.*; //从别的包里引用

java中的引用类型和值类型

值类型和引用类型的不同 [定义] 引用类型 表示你操作的数据是同一个,也就是说当你传一个参数给另一个方法时,你在另一个方法中改变这个变量的值,那么调用这个方法时,传入的变量的值也将改变. 值类型 表示复制一个当前变量传给方法,当你在这个方法中改变这个变量的值时,最初声明的变量的值不会变. [值类型] 值类型就是基本数据类型 基本数据类型常被称为四类 八种 整型:byte.short.int.long 浮点型:float.double 字符型:char 逻辑型:boolean [引用类型] 除了四

Java中的流概念

数据流的概念 在 Java 中,把所有的输入和输出都当做流来处理. “ 流 ” 是一个抽象概念,它代表任何有能力产出数据的数据源对象或者是有能力接收数据的接收端对象. “ 流 ” 屏蔽了实际的输入 / 输出设备中处理数据的细节.一个程序可以打开一个数据源上的流,然后按顺序读取这个流中的数据到程序中,这样的流称为输入流,其过程如图所示.一个程序也可以打开一个目的地的流,然后按顺序的把程序中的数据写入到这个目地中,这样的流称为输出流. 加深理解:输入输出是相对程序而言的. 流的分类 两种分法: 1.

java中锁的概念/介绍

前言 Java提供了种类丰富的锁,每种锁因其特性的不同,在适当的场景下能够展现出非常高的效率.本文旨在对锁相关源码(本文中的源码来自JDK 8和Netty 3.10.6).使用场景进行举例,为读者介绍主流锁的知识点,以及不同的锁的适用场景. Java中往往是按照是否含有某一特性来定义锁,我们通过特性将锁进行分组归类,再使用对比的方式进行介绍,帮助大家更快捷的理解相关知识.下面给出本文内容的总体分类目录: ? 1. 乐观锁 VS 悲观锁 乐观锁与悲观锁是一种广义上的概念,体现了看待线程同步的不同角

java中的数组概念

数组的定义形式: 动态初始化方式: 1.声明并开辟数组 String str[]=new String[3];//3表示数组的长度 2.分布完成 String str[]=null; str=new String[3]; 静态初始化 1.简化格式 String str [] = {"1","2","3"}; 2.完整格式 String str = new String[]{"1","2","3&q

Java中的引用类型Scanner类和随机类型Random

Scanner类 我们要学的Scanner类是属于引用数据类型,我们先了解下引用数据类型.   引用数据类型的使用 与定义基本数据类型变量不同,引用数据类型的变量定义及赋值有一个相对固定的步骤或格式. 数据类型 变量名 = new 数据类型(); 每种引用数据类型都有其功能,我们可以调用该类型实例的功能. 变量名.方法名(); Scanner类 Scanner类是引用数据类型的一种,我们可以使用该类来完成用户键盘录入,获取到录入的数据. Scanner使用步骤: //导包: import jav

Java中数组的概念

1.什么是二维数组?有几种表达方式?分别是什么? 答:多维数组即数组的数组,即数组的元素也是数组. 例:int[] [] a = {{1},{1,2},{1,2,3}}; 有三种方式 1).int [] [] a;  2).int [] a1 [];  3).int a2 [] []; *强烈推荐用第1种,不容易混淆a的数据类型: 2.多维数组的创建过程是什么? 答: 例:int [] [] a = new int [2] []; a[0] = {1,2,3}; a[1] = {4,5,6};

Java中数组的概念与特点

数组概念: 数组其实也是一个容器,可以用来存储固定个数相同类型的数据数组的定义 数组中存储的数据叫做元素 特点: 1.数组是引用数据类型 2.数组的长度是固定的,也就是说可以存储固定个数的数据 3.数组中的元素的类型必须一致,也就是说数组中存储的多个数据的数据类型一致 注意: 数组有定长特性,长度一旦指定,不可更改. 和水杯道理相同,买了一个2升的水杯,总容量就是2升,不能多也不能少. 原文地址:https://www.cnblogs.com/libinhong/p/10988744.html