一、Object类
1、object类介绍
(1) Object类是java中所有类的直接或间接父类。
(2)所有类对象都可以调用Object类中的方法。
(3) 所有类的对象都可以声明成Object类型的引用。
(4) 当没有为某一个类定义父类时,Java会自动定义Object类为其父类。
(5) Object是所有类的父类。如果你定义一个Object的数组,那么什么数据都可以存储进去。但你取出来的时候就要进行一个数据类型的强制转换。
注意:String对象也可以是Object对象的一个元素。
2、Object类中的方法
(1) Class对象:实质是Class文件,即该类编译之后产生的二进制字节码文件。
(2)获取Class对象的方式:
① Class.forName()。
②实例 对象.getClass()。
③ 类名.class。即:Class c1 =实例 对象.getClass(); Class c2 = 类名.class;//注意class是小写,并且后面不带()。
(3) getClass()方法 :
① 返回一个对象的实际类型,实质上是该对象所对应类的class文件对象。
②getName():返回class对象的全类名:实例对象.getClass()方法.getName();
③ getSimpleName():返回class对象的简类名:实例对象.getClass()方法.getSimpleName();
(4) toString()方法:
① 不重写该方法,对象.toString();时会输出该对象的全类名@对象的hashCode十六进制值:test2.Student@7852e922。
② 在类中重写toString()方法主要作用是返回该对象的所有属性值的字符串形式。
注意: String类中的toString()方法已经重写了Object类中的toString()方法。
(5) equals()方法 :
① object中的equals方法默认比较的两个对象的地址,和==等价。
② 如果比较两个对象各个属性值相同则为统一对象,需要重写hashCode和equals方法。hashCode的数值转换成十进制后的值就是其内存地址。
注意: String类与基本数据类型的封装类中重写了equals();方法,在String类型或者基本数据类型的封装类的实例对象.equals();方法,直接比较的是字符串内容是否相等。
举例说明:
① 如果对象不是String类型:
Animal a1 = new Animal("name");
Animal a2 = new Animal("name");
System.out.println(a1 == a2);//输出结果:false
System.out.println(a1.equals(a2));输出结果:false
② 如果对象是String类型,则重写了equals方法:
String s1=new String("suns");
String s2=new String("suns");
System.out.println(s1==s2); //输出结果:false,因为==比较的是内存地址
System.out.println(s1.equals(s2));//输出结果:true,因为重写了equals()方法,比较的是两个内容。
(6) 根据需要重写equals()方法 :
//根据需要,重写equals方法,判断非Sring类型对象的各个变量值内容是否相同
public boolean equals(Object stu) {
if(this==stu) {
return true;
}
if(stu==null) {
return false;
}else {
if(stu instanceof Student) {
Student other = (Student)stu;
if(this.age!=other.age) {
return false;
}
if (!this.name.equals(other.name)) {
return false;
}
if (!this.color.equals(other.color)) {
return false;
}
if (this.price!=other.price) {
return false;
}
return true;
}else {
return true;
}
}
}
public static void main(String[] args) {
Student stu = new Student(12,"小明","blue",20);
Student stu1 = new Student(12, "小明", "blue", 20);
System.out.println(stu.equals(stu1));//输出结果:true
}
(7) hashcode()方法 :返回当前对象的地址
(8) Finalize方法 :由对象的垃圾回收器调用此方法,不能主动调用。
(9) hashcode()和equals()的作用、区别、联系 :
① equals()相等的两个对象他们的hashCode()肯定相等,也就是用equal()对比是绝对可靠的。
② hashCode()相等的两个对象他们的equals()不一定相等,也就是hashCode()不是绝对可靠的。
③ 更详细内容,请参照某大佬博客:https://blog.csdn.net/bailu666666/article/details/81153815
(10) assertEquals(参数一,参数二)方法 :
//判断结果是否是期望得到的值,期望的是30,得到的是i,如果两者相同返回true,如果不同返回false
Assert.assertEquals(expected:30,i);
二、String类
1、方法介绍
(1) 字符串特点:
① final修饰的类、有序的字符序列,常量,字符串的内容永不改变【重点】。例如:String str = “abc”;str = “bcd”;这是错误的。
② 字符串不可改变,所以字符串可以共享使用。
③ 字符串效果上相当于char[ ]字符串数组,但是底层原理是byte[ ]字节数组。
(2) 创建字符串的方式:
①声明式创建,默认的创建方式String str=“abc”;
特点:
A:在字符串常量池中存储。
B:如果下一次依旧使用声明式方法创建就会去常量池进行匹配,如果存在则直接引用,不存在就重新创建。
C:好处:字符串可以重用。
②创建String实例对象:
A:String str1=new String(“abc”);
B:在堆和栈中开辟新的内存地址。
C:栈中存放首地址,堆中存放具体的值。
补充说明:“abcd”:会在字符串常量池中创建一个abcd,然后new String(“abcd”);又会在堆中创建一个abcd。如果字符常量池中已经存在"abcd"了,那么在常量池中不用创建"abcd"了,因为new了,所以需要在堆中创建一个对象,直接引用常量池中已经存在的"abcd"。
注意:
//下面两种写法,字符串的内容仍然是没有发生改变的 //下面有两个字符串:"Hello"、"Java"
//strA中保持的是地址值,本来的地址值是Hello的0x666,后来变成了Java的0x999;
String strA = "Hello";
System.out.println(strA);//输出:Hello
strA = "Java";
System.out.println(strA);//输出:Java
(3) String类中的常用方法:
方法名 | 含义 |
---|---|
String concat(String atr) | 将当前字符串和参数字符串拼接成为返回值新的字符串 |
char charAt(int i) | 返回指定位置的字符,返回的是char类型 |
int length() | 返回字符串的长度 |
String[] split(String regex) | 将字符串按照分隔符分割为一个字符串类型的数组 |
boolean startWith(String s) | 判断字符串是否以参数值作为开头 |
Boolean endWith(参数) | 判断字符串是否以某一个参数做结尾 |
trim() | 去掉两端的空格 |
String substring(int index) | 截取从参数下标位置一直到字符串末尾,返回最新字符串 |
String substring(int begin,int end) | 输出数组下标begin开始到数组下标end-1的字符串 |
int ComparTo(String str) | 按照字典顺序比较两个字符串。返回值是int类型的数字:str.comparTo(str1)。 |
boolean compareToIgnoreCase(String str) | 比较字符串的内容是否相同 |
boolean equals(Object obj) | 将当前字符串和参数字符串拼接成为返回值新的字符串 |
int indexOf(String str) | 返回字符以及子字符串第一次出现的下标,如果没有则返回 -1 |
int indexOf(String str,int fronIndex) | 返回指定字符串第一次出现在此字符串处的下标,从指定的索引fronIndex开始。 |
int lastIndexOf(String str) | 返回指定字符串最后一次出现的位置下标 |
replace(string a,string b) | 用字符a替换在调用字符串中所有出现字符b的地方进行替换,默认是替换所有。 |
toLowerCase() | 将字符串转换为小写 |
toUpperCase() | 将字符串转换为大写 。注意:汉字没法转换 |
ToCharArray() | 将字符转为char类型的数组 |
getBytes() | 将字符存储在字节数组byte中,输出的是字符对应的ASCII码数值 |
valueOf() | 函数返回指定对象的原始值 |
(4) 常用方法补充:
① String[] split(String regex):split方法的参数其实是一个:正则表达式;如果按照英文句点".“进行分割,必须写”\.“(两个反斜杠),因为”."在正则表达式里面有特殊含义,不加反斜杠会导致分割失败。
② int ComparTo(String str):
比较规则:
A:字符串长度相同时,先按照字符序列进行逐位比较,只返回第一次出现的不同字符的差值。
str.ComparTo(str1);如果差值为正整数,表示str中第一个不相同的字母Unicode值在str1前。
B:如果两个字符串长度不同,先按照第一比较规则进行,如果第一比较规则比较完仍然没有不同的字符,则直接返回字符串的长度的差值(str1.length()-str.length();)如果差值为正整数,表示str1(长).CompareTo(str(短))。
③ boolean equals(Object obj):比较字符串的内容是否相同:
参数可以是任何对象,只有参数是一个字符串并且内容相同的才会给出true,否则返回false。
注意 :
A:任何对象都能用Object接收。
B:equeals方法具有对称性,也就是a.equals(b)和b.equals(a)效果一样。
C:如果比较双方一个常量一个变量,推荐把常量字符串写在前面。原因看下面例子对比:
举例一:String str1="abc";
System.out.println("abc".equals(str1)); //true
System.out.println(str1.equals("abc")); //true
举例二:String str2=null;
System.out.println("abc".equals(str2)); //false
System.out.println(str2.equals("abc")); //编译错误,报:空指针异常
(5) 字符串拼接方法:
(1) 字符串拼接 +:
① 情况一:“”+new String();拼接方式,表示重写创建一个新的字符串对象new String(str9+str10);
② 情况二: " “+” “:”“+”" ;拼接方式,会在字符串常量池中新建拼接后的字符串对象。
String s1 = "helloworld";
String s2 = "hello" + "world";
System.out.println(s1 == s2); //结果为true
③ 情况三:字符串变量+字符事变量:相当与重新new一个新的字符串:即在堆中创建一个新的对象,不会在字符串常量池中。
String s1 = "helloworld";
String s2 = "hello" + "world";
System.out.println(s1 == s2);
String s3 = "hello";
String s4 = "world";
String s5 = s3 + s4;
System.out.println(s1 == s5);//false
System.out.println(s2 == s5);//false
④ 情况四:" “+字符事变量;相当与重新new一个新的字符串。
注意: String str = new String(“abc”);
A:在常量池中创建一个"abc”,又在堆中创建一个。
B:只要有""引起来的字符串,如果常量池中没有的话,都会在常量池中新建一个新建一个。
(2) concat()::与+作用相同,都会创建一个新的字符串。即在堆中创建一个新的对象,不会在字符串常量池中。
(3) StringBuffer();:
① 可变长度的字符串,在进行字符串拼接后始终是同一个对象,线程安全对象。
StringBuffer sb = new StringBuffer("hello");
StringBuffer sb1 = sb;
sb.append("world");
System.out.println(sb==sb1);//结果为true
}
② **注意:**StringBuffer sb1 = sb;这里是将sb对象的内存地址赋值给了sb1;sb与sb1指的是同一个对象,所以sb.append(“world”);就相当于sb1.append(“world”);
(4) StringBuilder():可变长度的字符串,在进行字符串拼接后始終是同一个对象,线程不安全对象。
(5) String,StringBuffer,StringBulider的区别:
① String是不可变常量,一旦定义赋值不能改变字符串的内容,拼接后会产生大量不可用字符串。
② StringBuffer , StringBulider是长度可变的字符序列,可以进行字符拼接。
③ StringBuffer是线程安全对象,它的所有方法都用synchronized进行修饰,线程安全效率相对低。
④ StirngBulider是线程不安全对象,线程不安全,效率相对高一点。
⑤ 速度:StringBuilder > StringBuffer > String
(6) 补充:
① 线程安全对象:用synchronized进行修饰的方法或代码块。一次只允许一个线程进行访问,线程安全,但效率低。
② 线程不安全对象: 没有使用synchronized进行修饰,线程不安全,效率高。