引用类型

Java 原子操作类(atomic包)

十年热恋 提交于 2020-01-28 11:00:24
专栏原创出处: github-源笔记文件 , github-源码 ,欢迎 Star,转载请附上原文出处链接和本声明。 原子操作类说明 当程序更新一个变量时,如果是多线程同时更新这个变量,可能得到的结果与期望值不同。我们可以用 并发关键字-volatile 、 并发关键字-synchronized 、 Lock 来解决并发读写问题。 但是从性能及语义上可能存在以下问题: volatile 不能保证组合操作的原子性(比如自增操作) synchronized 和 Lock 比较重量级 从 java1.5 开始,jdk 提供了 java.util.concurrent.atomic 包,这个包中的原子操作类,提供了一种用法简单,性能高效,线程安全的更新一个变量的方式。 atomic 包里提供原子更新类型分别是:原子更新基本类型,原子更新数组,原子更新引用,原子更新属性,这些类都是使用 Unsafe 实现的包装类。 目前 jdk1.8 , Atomic 开头的原子类,提供的方法、处理逻辑基本一致。差异部分表现在非数值类型的原子类支持自增自减操作。 jdk1.8 中新增了高性能原子类,参考《高性能原子类》一节介绍。 原子更新基本类型 Atomic 包提供了以下 3 个类: AtomicBoolean:原子更新布尔类型。 AtomicInteger:原子更新整型。 AtomicLong

堆栈和托管堆以及装箱和拆箱的理解

一个人想着一个人 提交于 2020-01-28 07:16:56
C#中的类型都来源于system.object类型,分为值类型和引用类型,分别存在内存的堆栈和托管堆中,值类型一般都是简单类型如int float double等,他们保存在堆栈中,是按后进先出(LIFO)原则存储数据项的一种数据结构。在计算机系统中,栈特指处理器支持的一块内存区域,其中保存着局部变量。工作方式是先分配内存的变量后释放(先进后出原则),所以一旦出了作用域就会被释放,所以在整个项目中无法使用,这个时候就想到了托管堆。 堆(托管堆)存储引用类型。此堆非彼堆,.NET中的堆由垃圾收集器自动管理。与堆栈不同,堆是从下往上分配,所以自由的空间都在已用空间的上面。现在来举个例子看看在内存中是如何通过堆栈和托管堆保存数据的。 Int a=100; 那么在堆堆栈中就会分出一块空间用来保存a,值为100,现在有一个方法 Int GetNum(int b) { b=500; Return b; } 这个时候把a的值作为参数传给这个方法,那么此时a的值会不会变成500呢,这个就是我们重点讨论的问题,方式就是一个临时的,用完就会被释放,其实我们只是复制了一个a的到方法里了,所有a的值不会改变 Student stu=new Student(); 我们知道上面的是一个引用类型的变量,它在内部的进程是 首先在堆栈中分出一块空间用来放Student stu的引用,然后将new Student(

C#与Java的比较

这一生的挚爱 提交于 2020-01-27 13:19:14
这篇文章对C#与Java做一个语言级的对比,方便C# 转Java或Java转C#的人有个大致了解。 这里大致用C#3.0与Java6.0做比较。 写完后得知维基百科里有更加全面得多的比较: http://en.wikipedia.org/wiki/Comparison_of_C_Sharp_and_Java .NET(C#) Java 基本类型 基本类型 C#中有无符号数,Java没有。 C#中有值类型,且可自己定义值类型的结构体(struct)。 Java中的基本类型(或叫基元类型)即为值类型, 但Java没有结构体,所以不能自定义值类型。 C#中的值类型(包括所有基本类型)间接继承自Object, 有自己的方法可以调用;Java中的值类型(即基本类型) 不继承自Object,只是简单的数据,没有方法可以调用。 C#中int等同于System.Int32,是值类型; bool等同于System.Boolean;等。 Java中int是基本类型,是值类型, 而Integer是引用类型,Integer是int的包装器, int自身没有方法,Integer有一些方法; int与Integer之间可隐式转换(导致装箱和拆箱), 但当Integer值为null的时候会在运行时抛出异常。 boolean等类似。 Java中的int与Integer的对应在C# 中类似int和Nullable

值类型和引用类型的深层理解

陌路散爱 提交于 2020-01-27 09:14:40
引言 山重水复疑无路,柳暗花明又一村,越探究越接近事物的本质。最近在学习原型模式(Prototype)时,发现原型模式本质就是对一个类原始数据的克隆,但在学习深拷贝和浅拷贝时又发现与值类型和引用类型有着千丝万缕的联系。回想好久都没有温习基础,于是就整理了值类型和引用类型的随笔,本文内容比较基础,对于想继续深入研究的同学可以查看IL更深入探究。 1.值类型(ValueType) 值类型包括:数值类型,结构体,bool型,用户定义的结构体,枚举,可空类型。 值类型的变量直接存储数据,分配在托管栈中。变量会在创建它们的方法返回时自动释放,例如在一个方法中声明Char型的变量name=’C’,当实例化它的方法结束时,name变量在栈上占用的内存就会自动释放 C#的所有值类型均隐式派生自System.ValueType。 结构体:struct(直接派生于System.ValueType)。 数值类型:整型,sbyte(System.SByte的别 名),short(System.Int16),int(System.Int32),long(System.Int64),byte(System.Byte),ushort(System.UInt16),uint(System.UInt32),ulong(System.UInt64),char(System.Char)。 浮点型:float

【C#进阶系列】12 泛型

冷暖自知 提交于 2020-01-27 00:03:26
泛型是CLR和编程语言提供的一种特殊机制,它用于满足“算法重用” 。 可以想象一下一个只有操作的参数的数据类型不同的策略模式,完全可以用泛型来化为一个函数。 以下是它的优势: 类型安全 给泛型算法应用一个具体的数据类型时,如果不兼容这种类型,就会编译错误或者报异常。 更清晰的代码 减少了强制转换,让代码更简洁 更佳的性能 用泛型可以有效避免装箱拆箱的操作,且无需在进行强制转换时验证是否类型安全,这两点都有效提高了代码的性能。 这就是为什么List<T>淘汰了ArrayList的原因,特别是在进行值类型操作时,因为装箱拆箱过多而差距很大。 约定:泛型参数要么为T要么以大写T开头,例如List<T>。 FCL中的泛型 System.Collections.Generic和System.Collections.ObjectModel命名空间中提供了多个泛型集合类和接口。 System.Collections.Concurrent命名空间则提供线程安全的泛型集合类。 System.Array类则提供了大量的静态泛型方法。 泛型的基础结构 .net 2.0才有泛型。 开放类型和封闭类型 之前我们讲到CLR会为各种类型创建类型对象,同样一个新的泛型类TroyList<T>也会创建一个类型对象,我们将具有泛型参数的类型称为 开放类型。 不能构造开放类型的实例 而指定了泛型类型实参的泛型类型称为

Java中的引用类型

五迷三道 提交于 2020-01-26 19:25:28
Java中引用类型 强引用 Persnon p = new Person(); 当指向Person对象的引用计数为0时,Person对象才能被垃圾回收器回收。 软引用 SoftReference sr = new SoftReference (new Person()); 获取软引用对象Person p = sr.get(); 当内存紧张的情况下,Person对象可能会被回收,即使它的引用计数为1 弱引用 WeakReference w = new WeakReference (new string()); 获取软引用对象String str = w.get(); 只要JVM中的垃圾回收器工作,就会被回收 虚引用 引用队列:当软引用或者是弱引用指向的对象被释放后,会将引用放在引用队列中(ReferenceQueue)。 虚引用是先将引用加入队列中再释放对象。 ReferenceQueue rq = new ReferenceQueue (); PhantomReference pr = new PhantomReference (new String(), rq); //pr.get() 为null rq.poll为pr 虚引用其实就是形同虚设,和没引用一样。其作用就是来检查对象是否将要被回收。并且没有get()方法来获取传入的对象。 注:以上的sr,w, rq都强引用

基本类型和引用类型分别作为形式参数的区别

╄→尐↘猪︶ㄣ 提交于 2020-01-26 14:43:05
方法的形式参数为基本数据类型 方法的形式参数如果是一个基本数据类型,形式参数的改变对实际参数没有影响,形式参数引用的为具体的数值。在方法调用完毕后,形式参数消失,数值也消失。 方法的形式参数为引用数据类型 方法的形式参数如果为一个引用数据类型,形式参数的改变会直接影响实际参数,形式参数引用的为内存空间地址值。故形式参数改变,通过地址值会将具体数值改变,即使方法调用完毕,仅形参地址值消失,空间依旧存储的为改变后的数值。 具体代码体现 class ArgsDemo{ public static void main(String[] args){ int a = 10 ; int b = 20 ; System.out.println(“a:”+a) ; //10 System.out.println(“b:”+b) ; //20 //调用了一个方法 //形式参数是基本数据类型,形参的改变不会影响实际参数 change(a,b) ; System.out.println(“a:”+a) ; //10 System.out.println(“b:”+b) ; //20 } public static void change(int a,int b){ System.out.println(“a:”+a) ; //10 System.out.println(“b:”+b) ; //20 a

线程堆栈(Thread Stack)和托管堆(Managed Heap)

孤人 提交于 2020-01-26 04:35:06
内存格局 通常分为四个区 全局数据区:存放全局变量,静态数据,常量 代码区:存放所有的程序代码 栈区:存放为运行而分配的局部变量,参数,返回数据,返回地址等, 堆区:即自由存储区 值类型变量与引用类型变量 的内存分配模型也不一样。为了理解清楚这个问题,首先必须区分两种不同类型的内存区域: 线程堆栈(Thread Stack)和托管堆(Managed Heap)。 每个正在运行的程序都对应着一个进程(process),在一个进程内部,可以有一个或多个线程(thread),每个线程都拥有一块“自留地”,称为“线程堆栈”,大小为1M,用于保存自身的一些数据,比如函数中定义的局部变量、函数调用时传送的参数值等,这部分内存区域的分配与回收不需要程序员干涉。所有值类型的变量都是在线程堆栈中分配的。 另一块内存区域称为“堆(heap)”,在.NET 这种托管环境下,堆由CLR 进行管理,所以又称为“托管堆(managed heap)”。用new 关键字创建的类的对象时,分配给对象的内存单元就位于托管堆中。 在程序中我们可以随意地使用new 关键字创建多个对象,因此,托管堆中的内存资源是可以动态申请并使用的,当然用完了必须归还。 打个比方更易理解:托管堆相当于一个旅馆,其中的房间相当于托管堆中所拥有的内存单元。当程序员用new 方法创建对象时,相当于游客向旅馆预订房间

C# 相等性判断

心不动则不痛 提交于 2020-01-26 02:48:56
C# 相等性判断有四个方法: 1 public static bool ReferenceEquals(object left, object right); 2 public static bool Equals(object left, object right); 3 public virtual bool Equals(object right); 4 public static bool operator ==(MyClass left, MyClass right); ReferenceEquals方法:使用场景是比较两个变量是否为同一个引用。对于引用类型,比较两个变量是否为同一个引用。对于值类型,先装箱,再比较装箱后的变量是否为同一个引用。显然,对于值类型,ReferenceEquals方法的结果必定是False。 ReferenceEquals方法,用户不应该重写。为什么?重写的原因是:原有的实现不能完成用户所期望的功能。ReferenceEquals方法就是比较变量是否指向同一个引用,用户不应该期望ReferenceEquals方法完成其他的功能。 静态Equals方法:使用场景是不清楚两个变量运行时的类型,因为变量可能是值类型、引用类型或者为Null。内部调用 left变量的实例Equals方法。静态Equals方法,用户不应该重写。 实例Equals方法

值类型和引用类型的嵌套

做~自己de王妃 提交于 2020-01-25 23:34:50
public class Test { public int a;//a是值类型,属于Test类的成员变量,位于Test实例化的对象所在的堆中 public int[] A;//A是引用类型,其值位于堆中,其引用也位于堆中 public void Method() { int b = 1;//b是局部变量,值类型,位于栈中 Console.WriteLine(b); int[] A = { 1, 2, 3 };//A是局部变量,引用类型,位于堆中 } } public struct Te { public int[] A;//A是引用类型,属于Te的成员变量,其引用位于栈中,其值在堆中 public int a;//a是值类型,位置栈中 public void Method() { Test test=new Test();//test是引用类型,其值位于堆中 } } 来源: CSDN 作者: 永恒星 链接: https://blog.csdn.net/enternalstar/article/details/103936772