1)static
Java中的特殊关键字
可用在:
- 变量
依赖于类直接存在,不依赖于对象实例存在,是类里面的一个独立存在
所有对象实例的变量值都共享存储在一个共同的空间(栈) - 方法
无需通过对象来引用,而通过类名直接引用
在静态方法中,只能使用静态变量而不能使用非静态变量
静态方法禁止引用非静态方法 - 类
- 匿名方法块
只在类第一次被加载时使用
执行顺序:static块>匿名块>构造函数
块代码缺陷:会给程序带来混淆,应当将块代码封装成函数再调用
2)单例模式
单例模式又名单态模式(Singleton)
限定某一个类在整个程序运行过程中,只能保留一个实例对象在内存空间
单例模式是GoF的23种设计模式(Design Pattern)中经典的一种,属于创建型模式类型
- 设计模式:用于解决在特定环境下、重复出现的、特定问题的解决方案
单例模式:保证一个类有且仅有一个对象
- 采用static来共享对象实例
- 采用private构造函数,防止外界new
3)final
可以用来修饰:
- 类
- 方法
- 字段
final类不能被继承
子类无法改写父类中的final方法
final变量不能再次赋值
- 如果是基本型别的变量则不能修改其值
- 如果是对象实例,那么不能修改其指针(但可以修改对象内部的值)
4)常量设计和常量池
常量:一种不会修改的变量
- Java没有constant关键字
- 不能修改,final
- 不会修改/只读/只要一份,static
- 方便访问public
Java中的常量
public static final
- 变量名字全大写,以字符连接
PI_NUMBER
一种特殊的常量:接口内定义的变量默认是常量
解释:实现接口需要遵循接口的定义,所以接口的变量就是以常量的形式存在
常量池:相同的值只储存一份,节省内存,共享访问
基本类型的包装类
- Boolean, Byte, Short, Integer, Long, Character, Float, Double
- Boolean: true, false
- Byte: -128~127
- Character:0~127
- Short, Integer, Long: -128~127
- Float, Double 没有常量池
字符串常量
public class StringConstantTest {
public static void main(String[] args){
String s1 = "abc";
String s2 = "abc";
String s3 = "ab"+"c";
String s4 = "a"+"b"+"c";
System.out.println(s1 == s2);//对
System.out.println(s1 == s3);//对
System.out.println(s1 == s4);//对
}
}
解释:都是常量,编译器将优化一切为abc存储到内存中
常量池的作用:
- 节约内存
- 共享访问
基本类型的包装类和字符串有两种创建方式
- 常量式赋值创建,放在栈内存(将被常量化)
- new对象进行创建,放在堆内存(不会常量化)
栈内存读取速度快,但容量小
堆内存读取速度慢,但容量大
Integer类
- 基本类型和包装类比较,将对包装类自动拆箱
- 对象比较,比较地址
- 加法会自动拆箱
String类
- 常量赋值(堆内存)和new创建(栈内存)不是同一个对象
- 编译器只会优化确定的字符串,并缓存
5)不可变对象和字符串
不可变对象:一旦创建,对象不能被更改,其内在的成员变量的值不能被修改
如:八个基本型别,String、BigInteger、BigDecimal
注:不可变对象是值不可变,指针可变
如何创建不可变对象
1、所有属性都是final、private
2、不提供setter方法
3、类是final的,或者所有的方法都是final
4、类中包含mutable对象,返回拷贝需要深度clone
不可变对象的优点:
只读、线程安全
并发,提高性能
可以重复使用
缺点:
制造垃圾,浪费空间
java字符串
典型的不可变对象
String定义:
String a = “abc”;//常量赋值,栈内存
String b = new String(“abc”);//new对象,堆内存
字符串内容比较:equals方法
是否指向同一个内存:==
- 字符串的加法
- 使用StringBuffer/StringBuilder类的append方法进行修改
- StringBuffer/StringBuilder的对象都是可变独享
- StringBuffer同步、线程安全、修改快速
- StringBuilder不同步、线程不安全、修改更快
在程序运行中,如果需要大量的字符串加减操作,应当使用StringBuffer和StringBuilder的方法