三个修饰符笔记(static,final,abstract)及StringBuffer的使用建议

static 静态的
可以修饰:
1.属性
类变量 全类公有 允许直接用类名访问
类加载: 当JVM第一次使用一个类时,需要通过ClassPath找到这个类对应的.class文件,
把这个文件包含的类的信息读入JVM并保存起来.一般的说,一个类只会加载一次!

类加载的时机:
(1)创建类的对象
(2)第一次访问类的静态成员
(3)加载子类必须先加载父类
注意: 如果仅仅是声明类的引用,不会类加载!

2.方法
静态方法 允许直接用类名调用
在静态方法中,只能访问类的静态成员
静态方法可以被子类的静态方法覆盖,而且没有多态(第三条不适用:不会根据对象实际类型去找子类覆盖后的方法)
对引用调用其静态方法,仅相当于对引用的引用类型调用静态方法

静态修饰的成员 跟对象无关 任何与对象有关系的关键字 方法 属性都不能够直接用

**注意:非静态方法可以直接访问本类中的静态方法或非静态方法,但是静态方法只能直接访问本类中的静态方法**

3.初始代码块
静态初始代码块中的代码,在类加载的时候执行一次
子类继承父类静态属性不会加载子类静态代码块
子类覆盖父类静态属性先加载父类静态代码块再加载子类静态代码块

final
可以修饰:
1.变量 一旦赋值 不能改变
对于final属性 系统不会提供默认值
如果是final实例变量 可以在初始化属性或是构造方法中赋值
如果是final类变量 可以在初始化属性或是静态初始代码块中赋值

2.方法
可以被子类继承,但是不能被子类覆盖

3.类
final修饰的类,不能被继承,没有子类,所有方法属性指向的都是本类的

intern() 返回一个对象在串池中的地址的方法
比如引用b b = b.intern();

String对象是由final修饰的
String 资源共享,不能被改变,如果要累加,就会每加一次创建一个新的对象,会造成空间浪费
StringBuffer可以被改变,在原有基础上累加,解决String累加造成空间浪费的问题

String str = "a";
StringBuffer sb = new StringBuffer(str);
sb.append("b"); //ab
sb.append("c"); //abc
sb.append("d"); //abcd
str = sb.toString();

使用StringBuffer的建议(实例):

StringBuffer s1 = new StringBuffer ();
	for(int i =0; i<50000; i++){
		s1.append("hello");
	}

StringBuffer s2 = new StringBuffer (250000);
	for(int i =0; i<50000; i++){
		s2.append("hello");
	}

实例结果:s2的速度要比s1的速度要快,原因如下:
StringBuffer内部实现的是char数组,默认初始长度为16,每当字符串长度大于数组长度时,
JVM会构造更大的新数组,然后将原先的数组内容复制到新数组,增加了开销,
这给我们的启示是在声明StringBuffer对象时,指定合适的capacity(也就是字符串长度*循环次数),不要使用默认值。

StringBuilder是非线程安全的,StringBuffer是线程安全的,总结如下:
(1)如果需要操作少量字符串,为了方便,我们用String;
(2)处理单线程大量字符串,用StringBuilder;
(3)处理多线程大量字符串,用StringBuffer;

abstract抽象的
1.类
抽象类只能声明引用,不能创建对象 (也就是一个类的半成品,还没有写完,不能拿来创建对象的时候修饰的)

2.方法
抽象方法 只有声明,没有实现

(用于让子类继承并覆盖父类的抽象方法并且利用多态实现父类抽象方法)

如果一个类中有抽象方法,这个类就必须是抽象类
子类继承抽象类,子类如果不希望也成为抽象类,就必须实现父类中声明的所有抽象方法

利用abstract,可以把方法声明放到父类中,方法实现留在子类中,更好的体现"共性放在父类"原则!

修饰符组合:
private static final 均不能和abstract联用

### StringBuffer使用占位符 在 `StringBuffer` 类中并没有直接支持类似于 `{}` 占位符的功能。然而,可以借助其他方式实现这一功能。一种常见的方式是利用正则表达式配合 `StringBuffer` 来完成占位符替换。 #### 方法一:手动查找并替换 可以通过遍历字符串找到所有的占位符,并将其替换成实际的内容: ```java public class PlaceHolderExample { public static void main(String[] args) { // 初始化带有占位符的 StringBuffer 对象 StringBuffer template = new StringBuffer("Hello {name}, you are {age} years old."); // 定义要替换的数据 String name = "Alice"; int age = 30; // 将模板中的{name} 替换为 Alice String result = template.toString().replace("{name}", name).replace("{age}", "" + age); System.out.println(result); } } ``` 这种方法虽然简单易懂,但在面对多个不同类型的占位符时显得不够灵活[^2]。 #### 方法二:使用正则表达式进行动态替换 更推荐的做法是采用正则表达式的模式匹配机制来进行更加复杂的占位符处理: ```java import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexPlaceHolderExample { private static final Pattern PLACE_HOLDER_PATTERN = Pattern.compile("\\{([^}]*)\\}"); public static void main(String[] args) { // 初始化带占位符的 StringBuffer 对象 StringBuffer template = new StringBuffer("Hello {name}, your id is {id}"); Matcher matcher = PLACE_HOLDER_PATTERN.matcher(template); // 假设有一个映射表存储着所有可能被使用的变量名及其对应的值 java.util.Map<String, Object> valuesMap = Map.of( "name", "Bob", "id", 12345L ); // 创建一个新的 StringBuffer 实例用于构建最终的结果串 StringBuffer sb = new StringBuffer(); while (matcher.find()) { String key = matcher.group(1); if (valuesMap.containsKey(key)) { matcher.appendReplacement(sb, Matcher.quoteReplacement(valuesMap.get(key).toString())); } else { throw new IllegalArgumentException("No value provided for placeholder: {" + key + "}"); } } matcher.appendTail(sb); System.out.println(sb.toString()); } } ``` 此代码片段展示了如何创建一个基于正则表达式的解决方案来解析和填充占位符。这种方式不仅限于简单的键值对替换,还可以扩展到更为复杂的应用场景中去[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值