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

常量
学习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");
    

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

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);
	}
}

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

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

缺点:
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>+

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

知识的搬运工-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值