栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

常量+不可变对象设计——重点

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

常量+不可变对象设计——重点

常量
学习Java常量,首先我们一个先理解一下常量的定义:常量是一种不可以修改的变量。例如 int a=10;即内存中分配一块空间给a,且a的值为10,之后便不能再改变了;在如Π=3.14。
在之前我们学习过,final与static关键字的用法。final定义的变量不能被修改,static修饰的变量只能有一份,只读操作。因此用final与static修饰变量就是常量。
Java中的常量:public static final num_Name
建议变量名字全大写。
注:final 与static的顺序可以对换;在前面我们也了解过static与final修饰的变量可以直接用类进行访问。
特殊的常量——接口内定义的变量默认是常量。
前面说过,接口里面的都是一个规范。
常量池

Java为很多基本类型的包装类/字符串都建立了常量池常量池就是相同的值只存储一份,节省空间,共享内存‘基本类型的包装类(8个基本类型)常量池内容:

 	Boolean:true,false
 	 Byte :-128——127
 	 Short  Long  Int:  -128——127
 	Character:0——127
package Static_final;

public class A {
	public static void main(String[] args) {
		Integer n1=127;
		Integer n2=127;
		//这里n1与n2指向一个内存空间(127 )
		System.out.println(n1==n2);//true
		Integer n3=128;
		Integer n4=128;
		System.out.println(n3==n4);//false
//		
		Integer n5=new Integer(127);
		System.out.println(n1==n5);//false
		
		Boolean b1=true;//布尔类型
		Boolean b2=true;
		//判断指针是否相同,对于基本类型浮点数double与float不存在常量池
		System.out.println("Boolean Test:"+String.valueOf(b1==b2));//true
		
		Byte b3=127;
		Byte b4=127;
		System.out.println("Byte Test"+String.valueOf(b3==b4));
		
		Character c1=127;
		Character c2=127;
		System.out.println("Character Test:"+String.valueOf(c1==c2));
		Character c3=1030;
		Character c4=1030;
		System.out.println("Character Test,超出范围的:"+String.valueOf(c3==c4));
		
		Short short1=-128;
		Short short2=-128;
		System.out.println("Short Test:"+String.valueOf(short1==short2));

		String s1="abc";
		String s2="abc";
		String s3="ab"+"c";//"ab""c"都是常量,编译器将优化,内存中并不会出现单独的“ab”,"c".这样内存就节省了,
		String s4="a"+"b"+"c";
		//s1=s2=s3=s4;四个变量指向同一个指针地址
	}
}
true
false
false
Boolean Test:true
Byte Testtrue
Character Test:true
Character Test,超出范围的:false
Short Test:true


基本类型的包装类和字符串有两种创建方式

常量式(字面量)赋值创建,放在栈内存(将被常量化)

 	Integer a=10;//赋值创建,读取快一些,内存少一些
 	String b="abc";
new对象进行创建,放在堆内存(不会常量化)
 	Integer c=new Integer(10)//不会常量化,不能进行编译优化
 	String d=new String("abc");

有常量也就自然有不可变对象,下面就来介绍不可变对象
不可变对象
不可变对象从字面意思就可以知道该对象一旦创建,着对象(状态/值)不能被更改了;
对象内在的成员变量的值不能被修改了。
八个基本类型别的包装类;StringBigIntegerBigDecimal等。
相反可变对象就是普通对象了

public class B {
	public static void main(String[] args) {
	//String就是一个不可变对象,即abc不会被修改了,而指针a的指向可以修改
		String a = new String("abc");//a是new创建的对象就是创建一个指针
		String b=a;//b与a指向同一个指针abc
		System.out.println(b);
		a="def";//a不再指向指针abc了,这个时候a就指向指针def,这个时候b还是在abc位置
		//创建过程,先创建一个def的空间,然后a的指针指向这个空间
		System.out.println(b);
	}
}

我们从上面可以得到,不可变对象创建后就不能改变其值,但是我们可以改变变量的指针。
上述的不可变对象都是基本类型,那么我们应该怎样自己创建不可变对象了。
首先

    immutable对象是不可改变,有改变,请clone/new一个对象进行修改所有的属性都是final(不能能修改)和private(私有的)不提供setter方法类是final的,或者所有的方法都是final类中包含mutable对象,那么返回值拷贝需要深度clone
    优点:只读,线程安全并发读,提高性能可以重复使用

缺点:
9. 制造垃圾,浪费空间,因为变量太多了。
下面使用字符串来介绍:

1.字符串是Java使用最多的类,是一种典型的不可变对象
2.String定义有两种,这两种的肯定不指向同一个空间
——String a=“abc”;//常量赋值,栈分配内存
——String b = new String(“abc”);//new对象,堆内存分配对象
3.字符串内容比较:equals方法
4.是否指向同一个对象:指针比较 “ == ”
Java常量池
1.保存在编译期间就已经确定的数据
2.是一块特殊的内存
3.相同的常量字符串(new常量的不算)只存储一份,节省空间,共享内存
字符串的加法:
String a=“abc”; //创建一个abc的空间,a指向这个空间里面
a=a+“def” ; //由于String不可修改,效率差
// 内存中重新分配一块abcdef空间,a的指针指向abcdef新空间中,舍弃了旧空间,此时旧空间没有用,还占空间,造成空间浪费。
1:使用StringBuffer / StringBuilder类的append方法进行修改(原地修改,如空间abc自觉变成abcdef,就不会产生新的空间)
2: StringBuffer / StringBuilder的对象都是可变对象,还可以节省大量时间。
StringBuffer (同步,线程安全,修改快速) / StringBuilder(不同步,线程不安全,修改更快)
使用: StringBuffer b=new StringBuffer (" a");
b.append( ‘abc’ );//a+cabc
append操作进度时间:StringBulider>StringBuffer>+

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/713003.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号