Object类就是最高的类,是java.lang.Object包里的类。java。lang包在使用的时候无需显式导入,编译时由编译器自动帮助我们导入。我们现在用到java中帮助文档API,我们以后要经常发用到API,并习惯于用它
API(Application Program interface)
API翻译说就是应用编程接口。
我们看看Object中有哪些方法:
方法摘要 | |
protectedObject | clone() |
boolean | |
protected void | finalize() |
Class<?> | getClass() |
int | hashCode() |
void | notify() |
void | notifyAll() |
toString() | |
void | wait() |
void | wait(long timeout) |
void | wait(long timeout, int nanos) |
现在先看看Object类中toString()方法。
我们看看如下代码:
class A{
public staticvoid main(String[] args){
Object o=new Object();
//我们看到一下打印结构都一样
System.out.println(o)
System.out.println(o.toString);
//我们看到一下打印结构都一样,String继承自Object
String str=”aaa”;
System.out.println(str)
System.out.println(str.toString);
}
}
通过以上代码,我们做下总结,当打印引用时,实际上会打印出引用所指对象的toString()方法的返回值,因为每个类都直接或间接地继承自Object,而Object类中定义了toString();因此每个类都有toString()这个方法。
为了更便于理解,我们重写toString方法
publicclassObjectTest {
publicstaticvoidmain(String[] args) {
Student stu=new Student();
//下面两个都打印helloworld
System.out.println(stu);
System.out.println(stu.toString());
}
}
class Studentextends Object{
@Override
public String toString() {
return"HelloWorld";
}
}
String类
在详解String类(字符串)之前我们先判断下,以下代码分别打印的是true还是false
publicclassStringTest {
publicstaticvoid main(String[] args) {
Stringstr=newString("aaa");
Stringstr2="aaa";
System.out.println(str==str2);//判断是true还是false
System.out.println("--------------");
Stringstr3="bbb";
Stringstr4="bbb";
System.out.println(str3==str4);//判断是true还是false
System.out.println("---------------");
Stringstr5=newString("ccc");
Stringstr6=newString("ccc");
System.out.println(str5==str6);//判断是true还是false
System.out.println("---------------");
Strings1="Hello";
Strings2="Hel";
Strings3="lo";
System.out.println(s1==s2+s3);//判断是true还是false
System.out.println("--------------");
System.out.println(s1=="hel"+"lo");//判断是true还是false
}
}
打印结果分别是:false,true,false,false,true。原因先不说,我们现在先看看”==”和equals()方法的区别和联系。
“==”和equals()方法的区别和联系
“==”即相等性,相等性的比较有以下两点:
1) 对于原生数据类型来说,比较的是左右两边的值是否相等。
2) 对于引用类型来说,比较左右两边的引用是否指向同一个对象,或者说左右两边的引用地址是否相同。
equals()方法,该方法定义在Object类当中,因此Java中的每个类都具有该方法,对于Object类的equals()方法来说,它是判断调用equals()方法的引用与传进来的引用是否一致,即这两个引用是否指向的是同一个对象。对于Object类的equals()方法来说,它等价于==。
那么,equals()方法既然对Object类等价于==,那么对于字符串是不是也一样适用呢?看看以下代码:publicclass StringTest2 {
publicstaticvoid main(String[] args) {
Stringstr=newString("aaa");
Stringstr2=newString("aaa");
System.out.println(str.equals(str2));//判断是false还是true
System.out.println("----------");
Stringstr3="bbb";
Stringstr4=newString("bbb");
System.out.println(str3.equals(str4));//判断是false还是true
}
}
以上结果分别是true,true。大家会奇怪,为什么会出现这样的结果,String不是继承了Object吗,特性怎么变得不一样?真正的原因其实是String类重写了父类Object类的equals()方法,通过看java源码可以得知。
那么我们进行总结:对于String类的equals()方法来说,它是判断当前字符串与传进来的字符串的内容是否一致。所以以后大家注意,对于String对象的相等性判断来说,请使用equals()方法,而不要使用==。
那么,我们来看看重写父类Object类equals()方法的普通类怎么实现String类中equals()方法。看如下代码:
publicclass EqualsTest {
publicstaticvoid main(String[] args) {
Student1stu1 =newStudent1("张三");
Student1stu2 =newStudent1("张三");
System.out.println(stu1==stu2);
System.out.println(stu1.equals(stu2));//打印true
}
}
class Student1 {
Stringname;
public Student1(String name) {
this.name = name;
}
@Override
publicboolean equals(Object obj) {
if(this==obj){ //判断两个引用是否指向同一个对象
returntrue;
}
if(objinstanceof Student1){ //判断形参obj是否是Student类的实例
Student1 stu =(Student1)obj;//强制转换成Student类
//Student1stu2=new Student1();
if(this.name==stu.name){ //判断两个类的属性是否相等
returntrue;
}
}
returnfalse;
}
}
String类详解
我们在详细了解String类前,我们看以下代码:
publicclassTest {
publicstaticvoid main(String[] args) {
Stringstr1="hello";
Stringstr2=" world";
Stringstr3=str1+str2; //其实生成了新的对象。
System.out.println(str3);//打印hello world
System.out.println(str3==str1+str2);//false,这里是引用地址的对比,可以看出str3是新的对象
System.out.println(str3.equals(str1+str2));//true,内容的对比
}
}
我们对上面总结下:String是常量,其对象一旦创建完毕就无法改变。当使用+拼接字符串时,会生成新的String对象,而不是向原有的String对象追加内容。
我们再看看以下代码,再来说说String类新的概念,常量池。
第一个: public static void main(String[] args){
String str1=”aaa”;
String str2=”aaa”;
System.out.println(str1==str2);//结果打印true
}
第二个:String s=newString("bbb");
String s2=newString("bbb");
System.out.println(s==s2);//false
System.out.println(s.equals(str2));//true
那么对于以上代码的我们来说说String能中重要的概念
常量池(String pool)
对于String str=”aaa”,采用字面值方式赋值,那么我们进行以下归纳:
1) 在不存在“aaa”的情况下,首先查找常量池中是否存在“aaa”这个对象,如果不存在,则在常量池中创建一个“aaa”,然后将常量池中的这个“aaa”对象的地址返回来,赋给引用变量str,这个str会指向常量池中的这个“aaa”字符串对象。
2) 如果存在“aaa”情况下,则不创建任何对象,直接将常量池中的这个“aaa”对象地址返回来,赋给str引用。
对于String s=new String(),采用的是new对象方式赋值
1) 首先在常量池中查找有没有“aaa”这个字符串对象,如果有,则不在常量池中再去创建一个“aaa”这个对象了,直接在堆中(heap)中创建一个“aaa”字符串对象,然后将堆中的这个“aaa”对象的地址返回来,赋给s引用,导致s指向了堆中创建的这个“aaa”字符串对象。
2) 如果没有,则首先在常量池中创建一个“aaa”对象,然后再在堆中(heap)创建一个“aaa”对象,然后将堆中的这个“aaa”对象的地址返回来,赋给s引用,导致s指向了堆中所创建的这个“aaa”对象
字符串拼接
我们看看以下代码:
publicclassStringBufferTest {
publicstaticvoidmain(String[] args) {
StringBuffer sb=new StringBuffer();
sb.append("hello").append(" world").append(" welcome");//@1
Stringresult=sb.toString();
System.out.println(result);
}
}
发现StringBuffer中append是完成字符串拼接,上面@1注释的也可以写成这样:
sb.append("hello");
sb.append(" world");
sb.append(" welcome");
关于字符串拼接,我们再看看以下有效的字符串拼接代码:
Strings=”100”+200;
Strings1=”boolean”+false;
。。。。
但是不能
String=100+200;(这是int类型了)
String=true+false;
包装类(Wrapper Class)
包装类是对什么东西来说的呢?它是针对于原生数据类型的包装。所有的包装类,都位于java.lang包。java中的8个包装类分别是什么呢?
1 int Integer
2 char Character
3 float Float
4 double Double
5 byte Byte
6 short Short
7 long Long
8 booleanBoolean
包装类两个重要概念:装箱和拆箱
所谓装箱,就是把基本类型用它们相对应的引用类型包起来,使它们可以具有对象的特质,如我们可以把int型包装成Integer类的对象,或者把double包装成Double,等等。
所谓拆箱,就是跟装箱的方向相反,将Integer及Double这样的引用类型的对象重新简化为值类型的数据。
下面关于包装类与原生数据类型互换代码。
publicclassToStringTest{
publicstaticvoid main(String[] args) {
//由原生数据类型转换为Interger类
int i=10;
Integerin=newInteger(i);
System.out.println(in);
//由Interger类转为原生类型int
int s=in.intValue();
System.out.println(s);
}
}