Object
1.是所有的类的总父类,只要是类就一定直接或者间接继承自Object
(Object 包含所有类)
2.内部存放着所有对象都需要拥有的方法
3.可以根据需求对其中的部分方法提供重写
常用方法
1.Class类对象 getClass(); 用来获取当前引用的实际对象类型
//创建一个学生对象Student student = new Student();//创建一个老师对象Teacher teacher = new Teacher();Person person = new Person();Person p1 = new Student();Person p2 = new Teacher();System.out.println(p1.getClass());System.out.println(p2.getClass());//判断p1和p2的实际对象类型是否相同System.out.println(p1.getClass() == p2.getClass());//fSystem.out.println(p1.getClass() == student.getClass());//tSystem.out.println(person.getClass() == student.getClass());//f
2.int hashCode(): 获取当前对象的哈希码值
- 重写原因:该方法默认关注的是对象地址,但是在实际开发的过程中,某些情况下需要关注的是对象内容,不是对象地址。所以需要重写
重写的规则
1,整型:直接相加
long 类型需要类型强转为int
2.浮点型:强转int后相加
3.引用类型:调用hashCode()方法加
类库中的引用类型(String, 包装类等):直接调用
自定义的引用类型:先重写该类的hashCode再调用
public class Student extends Person {private String name;private int age;private double score;private Teacher tea;//重写方法public int hashCode() {return age + (int) score + name.hashCode()+tea.hashCode();}//省略getter、setter、构造}public class Teacher extends Person{private String name;private int age;//重写方法public int hashCode() {return name.hashCode() + age;}//省略getter、setter、构造}
3.boolean equals(Object o);判断当前对象与参数对象是否相同
重写原因:该方法默认比较地址,但是实际开发中,在某些需求下需要比较对象内容,所以需要重写
重写规则:
public boolean equals(Object o){//Object o=new Student();//自反性:自己与自己比,一定相同if (this == o) {return true;}//非空判断+类型比较:与null值比或者实际对象类型不一致,一定不同if (o == null || this.getClass() != o.getClass()) {return false;}//类型强转:把参数对象类型强转为当前类型,方便比较属性值当前类名 引用名 = (当前类名) o;//进行属性值比较//用this对象和引用名的属性进行比较://基本类型==直接比较,引用类型调用equals方法进行比较//类库中的引用类型:直接调用//自定义的引用类型:重写对应类的equals,然后调用return ...;}
案例
public class Student extends Person {private String name;private int age;private double score;private Teacher tea;//重写方法public boolean equals(Object o){//Object o=new Student();//自反性:自己与自己比,一定相同if (this == o) {return true;}//非空判断+类型比较:与null值比或者实际对象类型不一致,一定不同if (o == null || this.getClass() != o.getClass()) {return false;}//类型强转:把参数对象类型强转为当前类型,方便比较属性值Student stu = (Student) o;//进行属性值比较return this.age == stu.age && this.score == stu.score && this.name.equals(stu.name) && this.tea.equals(stu.tea);}//省略getter、setter、构造}public class Teacher extends Person{private String name;private int age;//重写方法@Overridepublic boolean equals(Object o) {if (this == o) {return true;}if (o == null || this.getClass() != o.getClass()) {return false;}Teacher tea = (Teacher) o;return this.name.equals(tea.name) && this.age == tea.age;}//省略getter、setter、构造}
4.String toString():获取对象的详细内容
。特点:在直接查看引用名时可以调用
重写原因:该方法默认获取对象地址但是实际开发中,我们有可能需要查看对象属性信息,所以需要重写
重写规则:按照需求拼接字符串返回即可
public String toString(){
return "姓名:" + name + ",年龄:" + age + ",成绩:" + score;
//return name+age + score;
}
5.void finalize() :虚拟机调用进行垃圾对象回收
垃圾回收机制:当虚拟机内存不足时,不足以支撑新的对象创建,这个时候虚拟机就会自动调用垃圾对象的finalize 方法 对其进行回收销毁,释放空间
垃圾对象的判断标准:没有任何引用指向的对象(零引用机制)
手动垃圾回收:借助垃圾回收器(GC),通过System.gc()
实现手动垃圾回收
包装类
作用:将八大类型包装为引用类型,使其保留数值操作简单的基础之上可以处理null值
byte | short | int | long | float | double | char | boolean |
Byte | Short | lnteger | Long | Float | Double | Character | Boolean |
包装类型和基本类型
基转包
1,利用构造
包装类名 引用名=new 包装类名(基本类型);
2.利用valueOf方法
包装类名 引用名=包装类名.valueOf(基本类型);
包转基
利用xxxValue方法
基本类型 变量名=包装类对象.xxxValue();注:xxx表示对应基本类型名
拆箱封箱
-
JDK5.0之后,为了提高包装类型与基本类型之间转换的效率,提供了自动封箱和自动拆箱操作,使其可以直接相互赋值自动完成转换
1.封箱:基转包
2,拆箱:包转基
int n1=10;
//转为包装类型
Integer i1 = new Integer(n1);
Integer i2 = Integer.valueOf(n1);
//将i1转为基本类型
int n2 = i1.intValue();//自动封箱和拆箱
int n3=20;
Integer i3 = n3;
int n4 = i3;
基本类型与String
基本String
1,拼接双引号
String 引用名=基本类型+"";
String 引用名=""+基本类型;
2.利用valuO方法
String 引用名=String.valueOf(基本类型);
String 转基
利用parse方法
基本类型 变量名=对应包装类型.parseXxx(String类型);
注:Xxx对应基本类型,首字母大写
String类型转向其他类型时,字符串数据必须为对方能够接收的数据,否则会报出数据类型转换异常
int n1=10;
//转为String
String s1 = n1 + "";
String s2 = "" + n1;
String s3 = String.valueOf(n1);
//转为基本类型
int n2 = Integer.parseInt(s1);
System.out.println(n2);
String str = "abc";
// int n3 = Integer.parseInt(str); NumberFormatException数据类型转换异常
包装类型与String
包装String
1,拼接双引号
String 引用名=包装类型+"";
String 引用名=""+包装类型;
2,利用toString
String 引用名=包装类对象.toString();
String转包
与基转包的两种方式一致
案例
Integer i1=10;
//转为String
String s1 = i1 + "";
String s2 = "" + i1;
String s3 = i1.toString();
//转包
Integer i2 = new Integer(s1);
Integer i3 = Integer.valueOf(s1);String str = "abc";
// Integer i4 = new Integer(str); 数据类型转换异常
整数缓冲区
官方认定,-128至127是最常用的256个数字,为了避免包装类型数字重复使用带来的内存压力,在方法区中设立了整数缓冲区,缓冲区中存放该256个数字,当包装类型使用的数字在此范围内时,会直接引用缓冲区地址
== 比较引用类型时,地址值优先
案例
Integer i1 = 200;//封箱
Integer i2 = 200;
System.out.println(i1 == i2);//f
Integer i3 = 100;
Integer i4 = 100;
System.out.println(i3 == i4);//tInteger i5 = new Integer(100);
Integer i6 = new Integer(100);
System.out.println(i5 == i6);//fInteger i7 = new Integer(100);//堆地址(对象地址)-->缓冲区地址
Integer i8 = 100;//缓冲区地址
System.out.println(i7 == i8);//f
String
是内存中的常量,值在内存中一旦创建不可改
案例
String s1 = "abc";
String s2 = s1;System.out.println("s1:" + s1);//abc
System.out.println("s2:" + s2);//abc
System.out.println(s1 == s2);//ts2 = "edf";
System.out.println("s1:" + s1);//abc
System.out.println("s2:" + s2);//edf
System.out.println(s1 == s2);//f
创建方式
1.直接双引号赋值
String 引用名="值";
2,构造赋值
String 引用名=new String("值");
串池:全程字符串常量池。实际开发中,字符串是使用频率最高的数据类型,且复用度也很高,为了避免重复的字符串内容反复开辟空间造成的空间资源浪费,所以在方法区中设立了串池。目的是为了节省空间
区别
1.第一种创建方式:优先使用串池,先从串池中查找有无对应字符串内容,有。让引用直接指向对应串池地址,无。则先在串池中创建该字符串内容,然后再让引用指向
2.第二种 创建方式:无论如何都会开辟对象空间地址,开辟完对象空间之后,进入串池查找内容是否存在,存在。则直接存放对应串池地址,不存在。则先在串池中创建该内容,然后再存放串池地址
案例
String s1 = "abc";
String s2 = "abc";System.out.println(s1 == s2);//t
String str1 = new String("edf");
String str2 = new String("edf");
System.out.println(str1 == str2);//fString string1 = new String("abcdef");//堆地址+串池地址
String string2 = "abcedf";//串池地址
System.out.println(string1 == string2);//f
可变长字符串
值可改
-
StringBuffer:JDK1.0 线程安全,效率低
-
StringBuilder:JDK5.0 线程不安全,效率高
特点
-
必须通过构造创建
-
所有字符串内容操作必须借助方法完成
与String的区别
-
String是内存中常量,值不可改,可变长字符串值可改
-
String可以使用串池,可变长字符串无法使用串池
实际开发中,对一个字符串内容反复使用的频率要远远高于更改的频率,所以可以使用串池的String要优于可变长字符串
String的常用方法
-
String引用名.方法名(实参);
-
char charAt(下标):获取指定下标位置的元素
-
boolean contains(字符串):判断当前字符串是否包含指定内容
-
boolean endsWith(字符串):判断字符串是否以指定内容结尾
-
boolean startsWith(字符串):判断字符串是否以指定内容开头
-
boolean equals(字符串):判断字符串内容是否相同,区分大小写
-
boolean equalsIgnoreCase(字符串):判断字符串内容是否相同,不区分大小写
-
String toUpperCase():转全大写
-
String toLowerCase():转全小写
-
int length():获取字符串长度
-
int indexOf(字符串):获取指定内容第一次出现的下标
-
int lastIndexOf(字符串):获取指定内容最后一次出现的下标
-
boolean isEmpty():判断字符串内容是否为空,不能判比null值
-
String replace(旧字符串,新字符串):将字符串指定旧内容替换为新内容,全部替换
-
String[] split(字符串分隔符):将字符串按照指定分隔符进行分割,不保留分隔符
-
String subString(起始下标):将字符串从起始下标截取至末尾
-
String subString(起始下标,结束下标):将字符串从起始下标截取至结束下标前一位
-
String trim():去除字符串前后空格
-
byte[] getBytes():以byte数组的形式返回字符串的内容
-
char[] toCharArray():以char数组的形式返回字符串的内容
案例
package com.by.test; import java.sql.SQLOutput; public class TestString3 { public static void main(String[] args) { String s = "hello"; //char charAt(下标):获取指定下标位置的元素 System.out.println(s.charAt(0));//h System.out.println(s.charAt(3));//l //boolean contains(字符串):判断当前字符串是否包含指定内容 System.out.println(s.contains("llo"));//t System.out.println(s.contains("elo"));//f //boolean endsWith(字符串):判断字符串是否以指定内容结尾 System.out.println(s.endsWith("o"));//t System.out.println(s.endsWith("hello"));//t // boolean startsWith(字符串):判断字符串是否以指定内容开头 System.out.println(s.startsWith("h"));//t //boolean equals(字符串):判断字符串内容是否相同,区分大小写 System.out.println(s.equals("HeLlO"));//f //boolean equalsIgnoreCase(字符串):判断字符串内容是否相同,不区分大小写 System.out.println(s.equalsIgnoreCase("HeLlO"));//t //String toUpperCase():转全大写 System.out.println(s.toUpperCase());//HELLO //String toLowerCase():转全小写 String s2 = "ABC"; System.out.println(s2.toLowerCase());//abc //int length():获取字符串长度 System.out.println(s.length());//5 //int indexOf(字符串):获取指定内容第一次出现的下标 System.out.println(s.indexOf("l"));//2 //int lastIndexOf(字符串):获取指定内容最后一次出现的下标 System.out.println(s.lastIndexOf("l"));//3 System.out.println(s.lastIndexOf("a"));//-1 //boolean isEmpty():判断字符串内容是否为空,不能判比null值 System.out.println(s.isEmpty());//f String s3 = ""; System.out.println(s3.isEmpty());//t String s4 = null; //System.out.println(s4.isEmpty()); 空指针异常 //String replace(旧字符串,新字符串):将字符串指定旧内容替换为新内容 System.out.println(s.replace("l", "m"));//hemmo //String[] split(字符串分隔符):将字符串按照指定分隔符进行分割,不保留分隔符 String str1 = "a,11b,ggc,gggggd"; //按照,进行分割 String[] ss1 = str1.split(",");//[a b c d] for (int i = 0; i < ss1.length; i++) { System.out.print(ss1[i]+" "); } System.out.println(); //String subString(起始下标):将字符串从起始下标截取至末尾 System.out.println(s.substring(1));//ello //String subString(起始下标,结束下标):将字符串从起始下标截取至结束下标前一位 System.out.println(s.substring(1, 4));//ell //String trim():去除字符串前后空格 String s5 = " a b c "; System.out.println(s5.trim());//a b c //byte[] getBytes():以byte数组的形式返回字符串的内容 String s6 = "ABCD"; byte[] bs = s6.getBytes(); for (int i = 0; i < bs.length; i++) { // System.out.print(bs[i]+" ");//[65 66 67 68] System.out.print((char) bs[i]+" ");//[A B C D] } System.out.println(); //char[] toCharArray():以char数组的形式返回字符串的内容 char[] cs = s6.toCharArray();//[A B C D] for (int i = 0; i < cs.length; i++) { System.out.print(cs[i]+" "); } } }
char , byte,遍历下标 ,数值遍历
package com.by.test; public class StringTest { public static void main(String[] args) { String str = "abcdefg"; //转为char数组遍历 char[] cs = str.toCharArray(); for (int i = 0; i < cs.length; i++) { System.out.print(cs[i]+" "); } System.out.println(); //转为byte类型的数组 byte[] bs = str.getBytes(); for (int i = 0; i < bs.length; i++) { System.out.print((char)bs[i]+" "); } System.out.println(); //对字符串每部分进行分割 String[] ss = str.split(""); for (int i = 0; i < ss.length; i++) { System.out.print(ss[i]+" "); } System.out.println(); //遍历下标 for (int i = 0; i < str.length(); i++) { //根据下标获取当前元素 System.out.print(str.charAt(i)+" "); } } }