引用类型

7.final

时光总嘲笑我的痴心妄想 提交于 2020-01-14 05:47:23
文章目录 1. final的指令重排 1.1. 赋值`final属性`的指令重排 1.2. 读取`final属性`的指令重排 1.3. `final属性`为引用类型 1. final的指令重排 对于 final 域,编译器和处理器要遵守两个重排序规则。 在构造函数内对一个 final变量 赋值,与随后把这个被构造对象的引用赋值给一个变量,这两个操作之间不能重排序 初次读一个包含final变量的对象,与随后初次读这个final变量,这两个操作之间不能重排序 public class FinalExample { int i;           // 普通变量 final int j;         // final 变量 static FinalExample obj; public FinalExample () {   // 构造函数 i = 1;         // 写普通域 j = 2;         // 写 final 域 } public static void writer () {  // 写线程 A 执行 obj = new FinalExample (); } public static void reader () {  // 读线程 B 执行 FinalExample object = obj; // 读对象引用 int a = object.i; 

Java 深拷贝浅拷贝 与 序列化

落花浮王杯 提交于 2020-01-14 02:21:06
一、浅拷贝、深拷贝   浅拷贝会对对象中的成员变量进行拷贝:如果是基本类型,拷贝的就是基本类型的值;如果属性是内存地址(引用类型),拷贝的就是内存地址 ;   深拷贝,除了基本类型外,引用类型所引用的对象也会进行拷贝;(引用的对象只要求浅拷贝即可;若要深层拷贝,一般可利用序列化和反序列化来实现,也可手动实现各级引用对象的深层拷贝;)    二、实现:   浅拷贝:实现Cloneable接口,重写clone()方法,在clone()调用父类super.clone()即可;   深拷贝:1. 实现Cloneable接口,除了调用super.clone(),还要对引用类型手动调用其clone()方法并赋值;       2. 使用序列化来实现深拷贝,实现Serializable接口,没有必需重写的方法;        序列化可结合这两个方法使用: //这两个方法,并不是Serializable接口中定义的方法,但如果在对象中出现了,则会自动调用//当对象在序列化时,若实现了这个方法,则调用 private void writeObject(ObjectOutputStream steam) throws IOException{ stream.defaultWriteObject(); stream.writeObject(自定义对象); } //当对象在反序列化时,若实现了这个方法

Java学习08:字符和字符串

杀马特。学长 韩版系。学妹 提交于 2020-01-13 22:12:26
在Java中,字符和字符串是完全不一样的类型。 字符类型 字符类型char是基本数据类型,他是character的缩写。一个char保存一个Unicode字符: char c1="A" char c2="中" 因为Java在内存中总是使用Unicode表示字符,所以一个英文字符和一个中文字符都用char表示,他们都占用两个字节,要显示一个字符的Unicode编码,只需要将char类型直接赋值给int类型即可: int n1 = 'A'; // 字母“A”的Unicodde编码是65 int n2 = '中'; // 汉字“中”的Unicode编码是20013 还可以用转义符\u+Unicode来表示一个字符: // 注意是十六进制: char c3 = '\u0041'; // 'A',因为十六进制0041 = 十进制65 char c4 = '\u4e2d'; // '中',因为十六进制4e2d = 十进制20013 字符串类型 和char类型不同,字符串类型String是引用类型,我们通常用双引号来表示。一个字符串可以存储0到任意个字符: String s = ""; // 空字符串,包含0个字符 String s1 = "A"; // 包含一个字符 String s2 = "ABC"; // 包含3个字符 String s3 = "中文 ABC"; // 包含6个字符

关于Java的Object.clone()方法与对象的深浅拷贝

◇◆丶佛笑我妖孽 提交于 2020-01-13 04:15:17
文章同步更新在个人博客: 关于Java的Object.clone()方法与对象的深浅拷贝 引言 在某些场景中,我们需要获取到一个对象的拷贝用于某些处理。这时候就可以用到Java中的Object.clone方法进行对象复制,得到一个一模一样的新对象。但是在实际使用过程中会发现:当对象中含有可变的引用类型属性时,在复制得到的新对象对该引用类型属性内容进行修改,原始对象响应的属性内容也会发生变化,这就是"浅拷贝"的现象。关于浅拷贝,Object.clone()方法的描述也有说明: /** * Creates and returns a copy of this object. The precise meaning * ... * The method {@code clone} for class {@code Object} performs a * specific cloning operation. First, if the class of this object does * not implement the interface {@code Cloneable}, then a * {@code CloneNotSupportedException} is thrown. Note that all arrays * are considered to

【CLR Via C#】第5章 基元类型、引用类型、值类型

霸气de小男生 提交于 2020-01-12 09:37:02
  第二遍看这本书,决定记录一下加深印象。 值类型可以存储在堆和栈上,它是局部变量时存储在栈上,如果值类型是作为类的一个属性,那么就会存储在堆上; 引用类型有两块内存,一块存储引用地址(栈上),一块存储实际的对象(堆上)。 1,基元类型   什么事基元类型?基元类型是直接映射到FrameWork类库(FCL)中存在的类型,编译器直接支持的数据类型。比如int直接映射到System.Int32类型,就像是添加了using应用:using sbyte=System.SByte. C#基元类型 FCL类型 说明 sbyte System.SByte 有符号8位 byte System.Byte 无符号8位 short System.Int16 有符号16位 ushort System.UInt16 无符号16位 int System.Int32 有符号32位 uint System.UInt32 无符号32位 long Syetem.Int64 有符号64位 ulong System.Int64 无符号64位 char System.Char 16位Unicode字符 float System.Single 32位浮点值,即带小数 double System.Double 64位浮点值 bool System.Boolean True/False decimal [英] 'desɪml

值类型和引用类型

大兔子大兔子 提交于 2020-01-11 08:21:11
在C#中值类型的变量直接存储数据,而引用类型的变量持有的是数据的引用,数据存储在数据堆中。 常见的值类型数据有:整值型(整形,浮点型,十进制型),布尔类型,枚举类型; 引用类型有:接口,数组,Object类型,类,委托,字符串,null类型。 在C#中每种类型的存储方式有两种:1)分配在托管栈中;2)分配在托管堆中; 内存的分配有CLR管理(即公共语言运行时),这两种方法的区别是: 1)分配在托管栈中的变量会在创建它们的方法返回时自动释放,例如在一个方法中声明Char型的变量UserInput=C,当实例化它的方法结束时,UserInput变量在栈上占用的内存就会自动释放; 2)分配在托管堆中的变量并不会在创建它们的方法结束时释放内存,它们所占用的内存会被CLR中的垃圾回收机制释放。 看下面的代码: 1 static void Main(string[] args) 2 { 3 //当nStudent声明并赋值是,这时在托管栈上就会开辟一块内存来存储nStudent的值,当实例化nStudent的Main()方法结束时, 4 //nStudent在托管栈上占用的内存会自动释放。 5 int nStudent = 0; 6 //当声明strStuName时,这个时候“小明”存储在托管堆中,而托管栈中存储的是strStuName指向的引用。 7 string strStuName =

JAVA 中的null

对着背影说爱祢 提交于 2020-01-11 07:46:23
对于Java程序员来说,null是令人头痛的东西。时常会受到空指针异常(NPE)的骚扰。连Java的发明者都承认这是他的一项巨大失误。Java为什么要保留null呢?null出现有一段时间了,并且我认为Java发明者知道null与它解决的问题相比带来了更多的麻烦,但是null仍然陪伴着Java。 我越发感到惊奇,因为java的设计原理是为了简化事情,那就是为什么没有浪费时间在指针、操作符重载、多继承实现的原因,null却与此正好相反。好吧,我真的不知道这个问题的答案,我知道的是不管null被Java开发者和开源社区如何批评,我们必须与null共同存在。与其为null的存在感到后悔,我们倒不如更好的学习null,确保正确使用null。 为什么在Java中需要学习null?因为如果你对null不注意,Java将使你遭受空指针异常的痛苦,并且你也会得到一个沉痛的教训。精力充沛的编程是一门艺术,你的团队、客户和用户将会更加欣赏你。以我的经验来看,导致空指针异常的一个最主要的原因是对Java中null的知识还不够。你们当中的很多已经对null很熟悉了,但是对那些不是很熟悉的来说,可以学到一些关于null老的和新的知识。让我们一起重新学习Java中null的一些重要知识吧。 Java中的Null是什么? 正如我说过的那样,null是Java中一个很重要的概念

C#引用类型和值类型的对比(装箱与拆箱)

自作多情 提交于 2020-01-11 03:08:21
1***、 C#中有两种类型: 值类型和引用类型: 值类型的变量直接包含他们的数据,而引用类型的变量存储引用类型存储对他们的数据的引用,后者称为对象: 简单说:值类型直接存储其值,引用类型存储对值得引用.引用类型分为引用和引用的对象。 2***、 值类型:简单类型、枚举、结构 引用类型: 类类型、接口类型、数组类型和委托类型 3***、值类型与引用类型的内存存储 单纯的说值类型存储在栈上,引用类型存储在托管堆上是不对的。 4***、区别: 1) 托管堆: 同步块和方法表, x,y,托管堆上的需要GC来回收 线程堆栈: 没有同步块和方法表 2) 值类型赋值是重新创建一个副本 而引用类型的赋值是共享同一块内存(副本),是指向同一块内存(引用类型的名字相当于指向操作)。只是复制引用而不复制被引用识别的对象。(“引用”和“引用的对象”) 3) 值类型与引用类型的不同之处就在于值类型的变量直接包括他们的数据,而引用类型的变量把references存储到他们的数据库(Objects)中。 4) 所有的值类型从Object中继承来的。任何类型都不能由值类型派生而来,因此,值类型是封闭式的。 5***什么时候使用值类型 1)当类型是一个十分简单的类型,其中没有成员会修改类型的任何实例字段 2)类型不需要从其他任何类型继承 3)类型不会派生出其他任何类型 4)类型的实例较小 5

mybatis 框架设计思路

折月煮酒 提交于 2020-01-10 11:20:02
1. 编写自定义的配置文件和映射文件。 2. 使用Classloader加载全局配置文件,返回InputStream对象 3. 配置文件加载 全局配置文件加载,将XML信息存储到Configuration对象 使用sax Reader去读取InputStream对象,创建Document对象 使用dom4j+xpath语法去解析Document对象 解析environments标签 封装DataSource对象,放入Configuration对象中 解析mappers标签 映射文件加载,将XML信息封装到MappedStatement对象并放入Map集合 中,key为statement的id,value为MappedStatement对象 使用Classloader加载全局配置文件,返回InputStream对象 使用sax Reader去读取InputStream对象,创建Document对象 使用dom4j+xpath语法去解析Document对象 解析根标签中的namespace属性和select标签 解析id属性 解析parameterType属性,并处理成Class类型 解析resultType属性,并处理成Class类型 解析statementType属性(便于执行时,是选择Statement还是 preparedStatement) 解析SQL语句(#{}和${})

值类型和引用类型在栈和堆中的分配

谁说我不能喝 提交于 2020-01-10 03:25:47
类型基础及背后的工作原理 数据在内存中的分配与传递 值类型和引用类型它们在内存分配与传递上的区别 内存分配 首先要了解一下内存中栈和堆的概念。 栈(Stack) ##栈是一种先进后出的内存结构。 方法的调用追踪就是在栈上完成的。比如我们有一个main方法(程序入口), 在main方法中会调用一个GetPoint的方法。在线程执行时,会将main方法压入栈底(包括编译好的方法指令,参数,和方法内部变量),然后再将GetPoint的方法压入栈底,GetPoint中没有调用其它方法,压栈完毕。出栈顺序是先进后出,也就是后进先出,栈顶的方法GetPoint先执行完毕,然后出栈,所占内存清空,接着main方法执行后出栈,所占内存清空。 //示意图:自己脑补吧... 从上面方法的压栈出栈中可以看出: ##栈只能在一端对数据进行操作,也就是栈顶端进行操作。’ ##栈也是一种内存自我管理的结构,压栈自动分配内存,出栈自动清空所占内存。 另外值得注意的两点: ##栈中的内存不能动态请求,只能为大小确定的数据分配内存,灵活性不高,但是栈的执行效率很高。 ##栈的可用空间并不大,所以我们在操作分配到栈上的数据时要注意数据的大小带来的影响。 堆(Heap) ##堆与栈有所区别,堆在C#中用于存储实实例对象,能存储大量数据,而且堆能够动态分配存储空间。 ##相比栈只能在一端操作,堆中的数据可以随意存取。 #