java的内存分析
来源:互联网 发布:js触发click事件 a标签 编辑:程序博客网 时间:2024/06/05 22:46
储存数组其实不是对象,而是对象的引用地址(储存对象的计算机的内存地址)
值类型,当方法调用的时候,因为传递进 方法的值只是原变量的一个副本,所以改变了副本不会改变原变量。
引用类型,当方法调用的时候,因为传递进方法的也是一个副本,只不过是 引用的副本,这个引用的副本也是指向 原对象的,所以修改了引用副本就会影响到对象。
如果结合这个案例,彻底把这个过程分析清楚:
分析案例:
class Program { static void Main(string[] args) { int[] ints = { 1, 2, 3 }; int[] intsCopy = ints;//复制数组,使变量引用内存中相同的数组对象 Change(ints);//调用方法,传入引用 //ints :2 4 6 //intsCopy:2 4 6 int[] ints_second = { 1, 2, 3 }; int[] ints_secondCopy = ints_second; ChangeAndRef(ref ints_second);//注意ref传入方法的引用是哪一个,那么 该引用就指向方法体内的新对象。 //ints_second:11 12 13 //ints_secondCopy:2 4 6 } static void Change(int[] array) { for (int i = 0; i < array.Length; i++) { array[i] *= 2; } array = new int[] { 11, 12, 13 }; } static void ChangeAndRef(ref int[] array) { for (int i = 0; i < array.Length; i++) { array[i] *= 2; } array = new int[] { 11, 12, 13 }; }
第一步:int[] ints;这个是声明一个引用变量,这个时候不开辟内存
第二步:给数组初始化或者赋值,就会开辟内存,这里的开辟内存是值 用引用变量---指向--内存的地址--这个地址上有 一个对象(对象是占用内存的)
第三步:int[] intsCopy=ints;这是 声明一个 引用变量,让这个变量也---指向--内存中的地址---对象
第四步:调用方法,这个时候注意了,引用类型是把引用变量的副本信息,传递进方法里,这个引用变量的副本---对应---对象
第五步:因为引用副本所对应的地址也是内存中的对象,所以会修改对象,因此 原引用变量---对应内存中地址的对象(改变)
第六步:因为在方法体内 new 了一个新对象,就是开辟了一个新内存,那么方法体的引用变量是可以 指向这块内存的地址的,但是方法体外部的引用对象是无法指向这个方法体内的对象的,所以我们看到 方法1新 new int[] 未能改变引用变量--对应的对象
核心:
第二个方法体:利用ref 使得 引用了引用变量,也就是说修改了引用变量指向的对象。所以array=new int[],改变了原来的ints_second的引用--对象,但是并未修改ints_secondCopy的引用变量---所对应的对象。这个方法体:1.改变了原Ints_second的对象 2.在方法体内new一块新内存,让ints_second 指向了这块新内存上的对象。
值类型:
案例1:(void情况)
class Program { static void Main(string[] args) { int i = 5;//这里是Int类型所以是值类型 Console.WriteLine("The current i is {0}",i);//5 Change(i); Console.WriteLine("The now i is {0}",i);//5 ,这里可以看出值类型不会改变原变量的值 } static void Change(int i) { i *= 2; Console.WriteLine("The i is {0}",i);//10 } }
如果使用ref参数的话,那么方法体传递的就是对i的引用,那么就是会修改原i所对应的值的。
案例2:(有返回值的情况)
class Program { static void Main(string[] args) { int i = 5;//这里是Int类型所以是值类型 Console.WriteLine("The current i is {0}", i);//5 int new_i=Change(i); Console.WriteLine("The now i is {0}", i);//5 ,这里可以看出值类型不会改变原变量的值 Console.WriteLine("The new_i is {0}",new_i);//10,这里可以看出值类型的是把副本的值改变了,其实并没有改变原变量的值 } static int Change(int i) { i *= 2; Console.WriteLine("The i is {0}", i);//10 return i; }
}
引用类型:
案例3:(void情况)
class Program { static void Main(string[] args) { int[] ints = { 1, 2, 3, 4, 5 }; Console.WriteLine("Lengths is {0}", ints.Length);//5 Console.WriteLine("The current ints is:"); foreach (int i in ints) { Console.Write(i + ""); // 1 2 3 4 5 } int[] intsCopy = ints;//复制一份给intsCopy Console.WriteLine(); ChangeArray(ints); Console.WriteLine("The Now ints is:"); // 2 4 6 8 10,这里不一样了,变量引用的对象改变了!! foreach (int i in ints) { Console.Write(i + ""); } Console.WriteLine("The Now intsCopy is :"); foreach (int i in intsCopy) { Console.Write(i + "");//2 4 6 8 10 ,注意!!这里是原变量的复制版本居然也改变了,说明引用类型被方法调用修改是修改原变量的。 } } static void ChangeArray(int[] array) { for (int i = 0; i < array.Length; i++) { array[i] = array[i] * 2; } } }
案例4:(有返回值)
class Program { static void Main(string[] args) { int[] ints = { 1, 2, 3, 4, 5 }; Console.WriteLine("Lengths is {0}", ints.Length);//5 Console.WriteLine("The current ints is:"); foreach (int i in ints) { Console.Write(i + ""); // 1 2 3 4 5 } Console.WriteLine(); int[] intsCopy = ints;//复制一份给intsCopy int[] new_ints = ChangeArray(ints); Console.WriteLine("The new_ints is:"); foreach (int i in new_ints) { Console.Write(i + "");//2 4 6 8 10 } Console.WriteLine(); ChangeArray(ints); Console.WriteLine("The Now ints is:"); // 4 8 12 16 20 foreach (int i in ints) { Console.Write(i + ""); } Console.WriteLine(); Console.WriteLine("The Now intsCopy is :"); foreach (int i in intsCopy) { Console.Write(i + "");//4 8 12 16 20 } } static int[] ChangeArray(int[] array)//定义方法修改数组 { for (int i = 0; i < array.Length; i++) { array[i] = array[i] * 2; } return array; } }运行结果:Lengths is 5The current ints is:1 2 3 4 5The new_ints is:2 4 6 8 10The Now ints is:4 8 12 16 20The Now intsCopy is :4 8 12 16 20
- Java的内存分析
- java的内存分析
- java的内存分析
- Java的内存分析
- Java的内存分析
- Java语言的内存分析
- java的内存分析之一
- Java的内存模型分析
- java程序的内存分析
- 【Java EE】Java代码的内存分析
- java 的堆栈 的内存分析
- Java内存对象的逃逸分析
- Java内存分析,不可或缺的易筋经!!!
- Java内存对象的逃逸分析
- Java内存对象的逃逸分析
- JAVA程序内存溢出问题的分析
- Java内存溢出的分析和解决
- java内存泄漏的定位与分析
- 简单明了 -- mysql中的limit用法
- android-获取View的Width和Height-随心
- 第一个webservice案例
- 1.cocos2d CCLayer 的创建
- 如何在PCB上通过器件选择和布线达到降低噪声的目的?
- java的内存分析
- 使用NSMethodSignature和NSInvocation实现消息转发
- 如何在github上发起一个pull request
- OpenCV c接口与c++接口
- OpenCV成长之路(3):模仿PhotoShop中魔术棒工具
- 【Unity3D】【NGUI】本地生成API文档
- linux内核input子系统解析
- C++查漏补缺读书笔记三 指针与引用,动态绑定与静态绑定
- 微机xx