注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

刘小龙

成功需要的是一场持久的战役!

 
 
 

日志

 
 

[Java/Web]Java之Holder技术 (转)  

2014-12-09 17:15:55|  分类: 知识积累 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

前言

         Java区分值类型和引用类型。值类型就是基本的数值类型,如intdouble等。除此之外的都是引用类型。值类型和引用类型的区别可以通过下面这张图表达出来:

[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界

  [Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界

    定义了一个值类型,它的自身内容就是[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界;
[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界 

    定义了一个引用类型,它的自身内容是[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界,而[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界存储内容才是[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界

可以这么说,值类型是直接指向型,而引用类型是间接指向型。如果我们引入间接指向层级的概念,那值类型就是0级间接指向型,引用型就是1级间接指向型。如果这个概念成立,那更多级的间接指向型也是存在的。没错,在C/C++中,指针分为一级指针、二级指针…更多级指针。

引用传参

         Java在传递函数参数的时候对值类型和引用类型的处理是不一样的。如下图所示:

[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界 

我们定义了一个函数[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界,它被声明为接受一个值类型和一个引用类型。在调用[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界函数的时候,它的形参是重新分配的,就是说[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界的内存地址与[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界内存地址是不一样的,但是它们都是把自身的内容直接传递给了对应的形参。在这个过程中,值类型和引用类型的概念并未发生变化: [Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界的目标内容是直接存储在自身地址的,所以仍然是值类型;[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界目标内容存储在[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界内存地址中,所以仍然是引用类型。

         假设[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界函数的实现如下:

[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界

当我们执行完这个函数后,内存中的变化如下图所示:

[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界

         当执行[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界的时候,内存中发生变化的是[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界自身的内容,这就是值类型的赋值本质;当执行[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界的时候,内存中发生变化并不是[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界自身的内容,而是[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界指向的内存地址发生了变化,这就是引用类型的赋值本质。

        [Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界函数执行完了之后的内存表现如下图所示:

[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界

可以看出, [Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界的内容并未发生变化,而 [Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界的内容却发生了变化。这说明了值类型和引用类型的另一个应用场景上的区别:引用类型可以用于函数外向函数内传值,而值类型则不能

如何改变引用类型本身的内容?

         在实际的编码过程中,我们经常会遇到这样一种情况:我们在函数外并不想为引用类型分配空间,而是在函数内执行这个过程。仍然是上面的那个例子,但是[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界函数的实现发生了变化,如下图所示:

[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界

我们试图通过改变[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界的自身内容达到改变[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界的自身内容的目的,但这是不能成功的!为什么呢?

[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界

[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界执行的时候,[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界的自身内容发生了变化,指向了新的内存地址。但是当函数执行完了之后,却并未执行将[Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界的自身内容(反向)传递给 [Java/Web]Java之Holder技术 - lvan - lvan GoGo 的世界的过程。

Holder技术

         为了解决上面提到的将函数内分配的空间传递到函数外的过程,Holder技术被发现了。原理其实非常简单,引用类型在函数执行的前后可以改变的是引用类型指向的内容,那么将我们想要的引用类型封装在另外一个引用类型中就可以对我们想要的引用类型进行自由变化了。下面是一个展示Holder技术的完整的例子:

 

public class IntegerHolder {

 

         public Integer value;

        

         public IntegerHolder(Integer i)

         {

                   value = i;

         }

        

         public static void ChangeInteger(Integer i)

         {

                   i = new Integer(10);

         }

        

         public static void ChangeInteger(IntegerHolder i)

         {

                   i.value = new Integer(10);

         }

        

         public static void main(String args[])

         {

                   Integer i = new Integer(5);

                  

                   ChangeInteger(i);

                   System.out.println(i.intValue());

                  

                   IntegerHolder ih = new IntegerHolder(i);

                   ChangeInteger(ih);

                   i = ih.value;

                   System.out.println(i.intValue());

         }

        

}

 

模板Holder

 

public class RefHolder <F> {

 

         public F value;

        

         public RefHolder(F value) {

                   this.value = value;

         }

        

}


转载来自:http://blog.163.com/lvan100@yeah/blog/static/6811721420143955843770/

  评论这张
 
阅读(331)| 评论(1)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017