1.Object类常用6个方法
a.public int hashCode()
哈希编码:和内存地址有关,根据内存地址通过哈希算法计算出的一个哈希值。作用是通过比较哈希值得到两个对象是否相等,但是哈希值相等不一定两个对象就相同,比如两个字符串“Aa”和“BB”
两个字符串,hash编码不同,内容一定不同
两个字符串,hash编码相同,内容不一定相同
b. public final Class getClass()
用来获取全限命名
Class和反射有关,代表类的字节码对象。
c. public String toString()
重写该方法自定义对象的输出格式
d. public boolean equals(Object obj)
equals方法本质上和==是没有区别的,因为该方法来自于Object类,而其底层实现是通过==来做判断处理的;
但是对于重写过后的equals方法来说,它们就有区别了。
区别在于:重写后的equals方法用来判断两个对象的内容是否相同,比较的是堆内存中的对象;
== 是用来判断对象的引用是否相等,比较的是栈内存中的引用地址;
e. protected void finalize()
该方法的作用是作为一种临终遗言,在程序结束前会调用这个方法,所以可以用来记录垃圾清理结束时间
该方法:不建议程序员手动调用,垃圾回收会自动调用
如果想手动调用垃圾回收可以调用System.gc();
重点: final finally finalize 的区别
a.final修饰符(关键字)。被final修饰的类,就意味着不能再派生出新的子类,不能作为父类而被子类继承。因此一个类不能既被abstract声明,又被final声明。将变量或方法声明为final,可以保证他们在使用的过程中不被修改。被声明为final的变量必须在声明时给出变量的初始值,而在以后的引用中只能读取。被final声明的方法也同样只能使用,即不能方法重写。
b.finally是在异常处理时提供finally块来执行任何清除操作。不管有没有异常被抛出、捕获,finally块都会被执行。try块中的内容是在无异常时执行到结束。catch块中的内容,是在try块内容发生catch所声明的异常时,跳转到catch块中执行。finally块则是无论异常是否发生,都会执行finally块的内容,所以在代码逻辑中有需要无论发生什么都必须执行的代码,就可以放在finally块中。
c.finalize是方法名。java技术允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在object类中定义的,因此所有的类都继承了它。子类覆盖finalize()方法以整理系统资源或者被执行其他清理工作。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。
f. protected Object clone()
必须实现Cloneable接口,子类重写方法
分为浅克隆和深克隆(深克隆如果属性是另一种类的对象,那么这个属性所在的类也要实现接口并重写)
深克隆举例:
1 public class Student implements Cloneable { 2 private String name; 3 private Book book; 4 public String getName() { 5 return name; 6 } 7 public void setName(String name) { 8 this.name = name; 9 } 10 public Book getBook() { 11 return book; 12 } 13 public void setBook(Book book) { 14 this.book = book; 15 }
//关于重写克隆方法,在浅克隆时可以快捷键默认,不用重写内容,返回的是super.clone();对于返回的是父类的克隆方法的理解:
//可以了解一下Java的RTTI机制,super.clone()中的super是基类,但是并不是本质的Object类,
//而是JVM根据实际调用clone的类进行派生出来的Object对象,你可以近似理解每个类的派生基类就是本身
16 @Override 17 public Object clone() throws CloneNotSupportedException { 18 Student o = (Student)super.clone(); 19 Book b = (Book) o.getBook().clone(); 20 o.setBook(b); 21 22 return o ; 23 } 24 25 26 27 } 28 29 public class Book implements Cloneable{ 30 private String bookName; 31 32 public String getBookName() { 33 return bookName; 34 } 35 36 public void setBookName(String bookName) { 37 this.bookName = bookName; 38 } 39 @Override 40 protected Object clone() throws CloneNotSupportedException { 41 // TODO Auto-generated method stub 42 return super.clone(); 43 } 44 45 } 46 public class Test { 47 public static void main(String[] args) throws Exception { 48 Student st = new Student(); 49 Book book = new Book(); 50 book.setBookName("西游记"); 51 st.setBook(book ); 52 st.setName("张三"); 53 54 Student clone = (Student) st.clone(); 55 System.out.println(st == clone); 56 System.out.println(st.getName()+st.getBook().getBookName()); 57 System.out.println(clone.getName()+clone.getBook().getBookName()); 58 st.setName("花花"); 59 book.setBookName("红楼梦");// 60 System.out.println(st.getName()+st.getBook().getBookName()); 61 System.out.println(clone.getName()+clone.getBook().getBookName()); 62 63 } 64 } 65 执行结果 66 false 67 张三西游记 68 张三西游记 69 花花红楼梦 70 张三西游记
2.String常用方法
构造方法
public String()
public String(String original) String str1 = new String();这句话在堆中开辟了空间,并且里面存了一个空数据,即“”而不是“ ”一个空格
public String(byte[] bytes)
public String(byte[] bytes,int offset,int length)
public String(char[] value)
public String(char[] value,int offset,int count)
关于String str1 = new String(“aaa”);和String str2 = “aaa”;的不同
a.String str1 = new String(“aaa”)是在堆中分配了一个空间,然后在常量池中找有没有“aaa”这个字符串对象,如果没有就开辟一块空间,并把对象地址存到堆中
b.String str2 = “aaa” 是直接到常量池中找,因为之前我们new了“aaa”,所以常量池中存有,直接把对象地址存在了栈中
如果用==比较,两者是不同的,如果用equals比较,两者是相同的,因为String内部重写了equals方法,比较的是两个对象。
关于字符串参数传递,原来的变量的值有没有改变的问题,答案是没有改变,因为String是不可变字符串类,假设String str3 = new String("bbb"),直接看代码把。
1 public class StringTest { 2 public static void main(String[] args) { 3 String str1 = new String("aaa"); 4 String str2 = "aaa"; 5 System.out.println(str1.hashCode()); 6 System.out.println(str2.hashCode()); 7 String str3 = new String("bbb"); 8 System.out.println("没传参之前的str3: " + str3); 9 changeString(str3);// 调用方法并传参 10 // 结果都是一样的,只是常规思维固化了我们的理解,以为两个str3都是一个变量并且通常认为基本数据类型是值传递,复制的是值, 11 // 原来的变量并没有改变;引用类型传递的是地址,原来的变量会被改变 12 // 正确理解 a.str3只是一个局部变量,作用范围是自己的方法体内,只是两个变量名相同而已 13 // b.String是特殊的引用类型,并且是不可变字符串,所以传参只是把原来常量池中的"bbb"的地址给他,它去常量池里面先找 14 // ccc ,发现没有ccc ,就开了一块空间放ccc 然后把两者拼接 在常量池中找bbbccc,发现没有就又开空间放置bbbccc,并把地址给了 15 // changeString()方法中的str3 ,所以前后一共开辟了三块空间。 16 System.out.println("传参后的str3: " + str3); 17 18 } 19 20 static String changeString(String str3) { 21 str3 += "ccc"; 22 return str3; 23 24 } 25 26 } 27 28 执行结果: 29 96321 30 96321 31 没传参之前的str3: bbb 32 传参后的str3: bbb
boolean equals(Object obj)
boolean equalsIgnoreCase(String str):忽略大小写,相同的位置,大小写不同认为相同
boolean contains(String str):是否包含某个字符串
boolean startsWith(String str):是否以某个字符串开始
boolean endsWith(String str)
boolean isEmpty():数据是否是空字符串
int length() 字符串的长度
char charAt(int index) 返回字符串中指定位置的字符
int indexOf(int ch) 查找指定字符的下标
int indexOf(String str) 查找指定字符串的下标
int indexOf(int ch,int fromIndex)
int indexOf(String str,int fromIndex)
String substring(int start) 截取子串
String substring(int start,int end)
byte[] getBytes() String还原成字节数组
char[] toCharArray() String转成成字符数组
static String valueOf(char[] chs) 字符数组--->字符串
static String valueOf(int i) 整数--->字符串
String toLowerCase() 全部转小写
String toUpperCase() 全部转大写
String concat(String str) +字符串拼接
String replace(char old,char new) 字符替换
String replace(String old,String new) 字符串替换
String trim() 修剪,去掉字符串前后的空格
int compareTo(String str) 判断两个字符的大小关系
int compareToIgnoreCase(String str) 判断两个字符的大小关系,忽略大小写
StringBuffer和StringBuilder
StringBuffer:也是用来存储字符串,
他和String不是兼容类型,不能自动类型转换和强制类型转换
String转StringBuffer直接构造方法转,StringBuffer转String直接toString
StringBuffer是一个可变字符串
线程安全,效率低
常用方法:
public StringBuffer append(String str):添加到尾部
public StringBuffer insert(int offset,String str):添加到指定位置
public StringBuffer deleteCharAt(int index) 删除指定位置的字符
public StringBuffer delete(int start,int end) 删除一段字符串
public StringBuffer replace(int start,int end,String str)
public StringBuffer reverse()
截取子字符串--返回值类型是String类型,本身没有发生改变
public String substring(int start)
public String substring(int start,int end)
StringBuilder 方法和StringBuffer没有区别
StringBuilder是一个可变字符串
线程不安全,效率高
String,StringBuffer,StringBuilder的区别
String :不可变字符串
StringBuffer,StringBuilder:可变字符串
StringBuffer:线程安全,效率低
StringBuilder:线程不安全,效率高