Java工程师成长修炼手册:01--Java基础特性和字符串
一.三大特性
1.封装
封装,把对象的属性封装起来(使用private修饰符),不被外部程序直接随意调用或修改成员变量。只能通过对象使用public修饰符的set 和 get 方法,来设置和获取成员变量的值。也可以把只在本类内部使用的方法使用 private。另外,还可以封装,隐藏一些方法,需要用的时候,就调用这些方法。这些就是封装。
封装的优点
- 良好的封装能够减少耦合,可以独立地开发、优化和修改。
- 类内部的结构可以*修改,更容易理解,调试的时候可以不影响其他模块。
- 隐藏信息,实现细节。
- 可以偷懒,把代码封装起来,以后要用的时候,就直接调用,增强了代码的复用性
public class Receipt {
private Date payDate;
private String payNo;
private float amount;
public Date getPayDate() {
return payDate;
}
public void setPayDate(Date payDate) {
this.payDate = payDate;
}
public String getPayNo() {
return payNo;
}
public void setPayNo(String payNo) {
this.payNo = payNo;
}
public float getAmount() {
return amount;
}
public void setAmount(float amount) {
this.amount = amount;
}
}
2.继承
一个类只能使用一次继承关系,子类继承父类的非private属性和方法,在子类中可以访问父类的非private属性和方法。
例如,Cat 和 Animal 。Cat类继承Animal 类,Cat是子类,Animal 是父类,子类能够访问父类的非private属性和方法。
public class Animal{
public String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void say(){
System.out.println("我是动物");
}
}
public class Cat extends Animal{
public String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Test
public void test(){
Animal animal = new Animal();
animal.say();
}
}
输出结果
我是动物
继承目的:代码复用。
3.多态
多态的三个必要条件
一、要有继承;
二、要有重写;
三、父类引用指向子类对象。
多态的实现方式:接口实现,继承父类进行方法重写,同一个类中进行方法重载
多态分为编译时多态和运行时多态:
编译时多态主要指方法的重载
运行时多态指程序中定义的对象引用所指向的具体类型在运行期间才确定
运行时多态有三个条件:
继承
覆盖(重写)
向上转型
下面的代码中,水果类(Fruit)有两个子类: Apple 和 Banana,它们都覆盖了父类的 eat() 方法,并且在 main() 方法中使用父类 Fruit 来引用 Apple 和 Banana 对象。在 Fruit 引用调用 eat() 方法时,会执行实际引用对象所在类的 eat() 方法,而不是 Fruit 类的方法。
public class Fruit {
public void eat() {
System.out.println("Fruit is delicious...");
}
}
public class Apple extends Fruit {
public void eat() {
System.out.println("Apple is delicious...");
}
}
public class Banana extends Fruit {
public void eat() {
System.out.println("Banana is delicious...");
}
}
public class Music {
public static void main(String[] args) {
List<Fruit> fruits = new ArrayList<>();
fruits.add(new Apple());
fruits.add(new Banana());
for(Fruit fruit : fruits) {
fruit.eat();
}
}
}
二.基本数据类型
Java基本数据类型有8种:byte(位),short(短整数),int(整数),long(长整数),float(单精度),double(双精度),char(字符),boolean(布尔值)
布尔型:boolean
整数型:byte、short、int、long
浮点型:float、double
字符型:char
8 种基本类型默认值以及包装类如下:
包装类型
基本类型的初始值如int为0,boolean为false,而包装类型的初始值为null
三.字符串
1.String 特性
String 被声明为 final,因此它不可以被继承。一旦创建了新的String对象,它的值就无法改变。
对String 对象的任何改动,其实就是创建了一个新的对象,再把引用指向该对象。
String s = “程序员,你还好吗?”;
System.out.println("s = " + s);//程序员,你还好吗?
s = "Hello World";
System.out.println("s = " + s);//Hello World
2.字符串创建
字符串创建的两种方式:
String str = "abcdefg";
String str = new String("abcdefg");
3.考察
String string1 = "测试";
String string2 = string1;
String string3 = new String(string1);
System.out.println(string1 == string2);//true
System.out.println(string1 == string3);//false
string1 和string2 比较的时候,比较的是它们的内容,因此为true。创建String3的时候,虽然内容是和 string1 一样的,但是创建了新的对象,地址也是不一样的。因此为false
4.常见的String方法
String str1 = "你有对象吗?";
str1 = str1.concat("New 一个对象出来");
System.out.println(str1);//你有对象吗?New 一个对象出来
System.out.println(str1.endsWith("没有"));//false
String str2 = "你有对象吗?";
System.out.println(str1.equals(str2));//false,str1的内容和st2不一样了
System.out.println(str1.hashCode());//-781657258
System.out.println(str2.hashCode());//1250370201
String str3 = "hello world";
System.out.println(str3.indexOf("world"));//6,下标从0开始
System.out.println(str3.indexOf("test"));//-1没找到对应的值,返回-1
System.out.println(str3.length());//11
System.out.println(str3.replace("hello","Java"));//Java world
System.out.println(str3.substring(2));//llo world 截取字符串,从第3个位置开始(下标从0开始),到最后一个位置
System.out.println(str3.substring(4,8));//o wo 截取字符串,从第5个位置开始,到8个位置结束
// 注意:String substring(int beginIndex, int endIndex)左闭右开
//(0 1) 开区间就是端点不能取 这里就是 0 和 1 不能取
//【0 1】 闭区间就是端点可以取 这里就是 0 和 1 可以取
String str4 = " 你老婆打你吗? ";
System.out.println(str4.trim());//你老婆打你吗?
String str5 = "我" + "单身";//这里的 + 的作用相当于concat()
String str6 = "我单身";
System.out.println(str5.equals(str6));//true
6.String、StringBuffer、StringBuilder的区别
- 可变性
String 是不可变的,长度大小都不可变
StringBuffer 和 StringBuilder 是可变的,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不会产生新的对象 - 线程安全
String 不可变,因此是线程安全的
StringBuilder 不是线程安全的(不能同步访问)
StringBuffer 是线程安全的,内部使用 synchronized 进行同步 - 使用
使用少量的数据用 String ;
单线程情况下,频繁的修改,大量的数据,用StringBuilder ;
多线程情况下,要求线程安全,频繁的修改,大量的数据,用StringBuffer ;
由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。至于StringBuffer,很少很少,基本上很少,真的很少会使用。因为大多数时候,我们需要的不仅仅是线程安全,而是锁。所以,实际开发情况,StringBuffer很少使用
StringBuffer stringBuffer = new StringBuffer("欢迎来到");
stringBuffer.append("Java世界");//拼接字符串
System.out.println(stringBuffer);//欢迎来到Java世界
System.out.println(stringBuffer.insert(0,"您好:"));//您好:欢迎来到Java世界 在下标为0的位置插入字符串
System.out.println(stringBuffer.reverse());//界世avaJ到来迎欢:好您 字符串反转
StringBuilder 和 StringBuffer继承了AbstractStringBuilder ,所以它们的方法是一样的
public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence
public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence
7. “==” 和 equals 的区别是什么?
基本数据类型、字符串、对象
对于基本数据类型:只有==, 比较的是两者之间的值,没有equals ;
对于字符串:== 比较的是内存地址,equals比较的是值,上面说到,new 一个String,会产生不同的对象,内存地址会发生变化 ;
对于对象:== 比较的是内存地址,equals判断是否同一对象,跟 == 一样;
① “==” 解读
对于基本数据类型、字符串、对象 == 的作用效果是不同的,如下所示:
基本类型:比较的是值是否相同;
字符串:比较的是内存地址是否相同。
对象:比较的是内存地址是否相同。
int a = 3;
int b = 3;
System.out.println(a==b); // true
String str1 = "Test";
String str2 = "Test";
String str3 = new String("Test");
System.out.println(str1==str2); // true
System.out.println(str1==str3); // false 创建str3的时候,产生新的内存地址,所以比较结果为flase
System.out.println(str1.equals(str2)); // true
System.out.println(str1.equals(str3)); // true
② equals 解读
对于字符串、对象 equals 的作用效果是不同的,如下所示:
字符串:比较的是两者之间的值是否相同。
对象:比较的是内存地址是否相同,即是否是同一个对象。
public void test() {
Integer integer1 = 1;
Integer integer2 = 1;
String str1 = "Test1";
String str2 = "Test1";
System.out.println(integer1 == integer2); // true
System.out.println(integer1.equals(integer2)); // true
System.out.println(str1 == str2); // true
System.out.println(str1.equals(str2)); // true
String str3 = new String("测试");
String str4 = new String("测试");
System.out.println(str3 == str4); // false
System.out.println(str3.equals(str4)); // true
Animal animal_1 = new Animal("动物");
Animal animal_2 = new Animal("动物");
System.out.println(animal_1 == animal_2); // false
System.out.println(animal_1.equals(animal_2)); // false
}
public class Animal {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Animal(String name) {
this.name = name;
}
}
8.String str=new String(“你的头发还好吗”) 创建了几个对象?
答:创建了两个对象,第一个对象是"你的头发还好吗",第二个对象是把"你的头发还好吗"指向str
9.StringUtils简介
StringUtils 方法的操作对象是 Java.lang.String 类型的对象,是 JDK 提供的 String 类型操作方法的补充,在org.apache.commons.lang3.StringUtils包下。StringUtils中所有方法都是static的,所以我们不用自己手动去创建对象,直接通过类名就可以调用其方法了。
常用方法:
public static String trim(String str):该方法去除str两端的空格
public static boolean isEmpty(final CharSequence cs):判断该字符串是否为空,为空的标准是 str==null 或 str.length()==0 。
public static boolean isBlank(final CharSequence cs):判断该字符是否都是空字符("")、null、或者whitespace(空格、制表符\t、换行符\n、换页符\f和回车符\n)
System.out.println(StringUtils.isEmpty(null));// true
System.out.println(StringUtils.isEmpty(""));// true
System.out.println(StringUtils.isEmpty(" "));// false 注意在 StringUtils 中空格作非空处理
System.out.println(StringUtils.isEmpty(" "));// false
System.out.println(StringUtils.isEmpty("Java"));// false
System.out.println(StringUtils.isEmpty(" Java "));// false
System.out.println(StringUtils.isBlank(null));// true
System.out.println(StringUtils.isBlank(""));// true
System.out.println(StringUtils.isBlank(" "));// true
System.out.println(StringUtils.isBlank("\t \n \f \r"));// true 对于制表符、换行符、换页符和回车符