集合(一)之Object类和String类以及包装类详解


Object类就是最高的类,是java.lang.Object包里的类。javalang包在使用的时候无需显式导入,编译时由编译器自动帮助我们导入。我们现在用到java中帮助文档API,我们以后要经常发用到API,并习惯于用它

 

APIApplication Program interface

API翻译说就是应用编程接口。

我们看看Object中有哪些方法:

方法摘要

protectedObject

clone()
创建并返回此对象的一个副本。

boolean

equals(Object obj)
指示其他某个对象是否与此对象相等

protected void

finalize()
当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。

Class<?>

getClass()
返回此 Object的运行时类。

int

hashCode()
返回该对象的哈希码值。

void

notify()
唤醒在此对象监视器上等待的单个线程。

void

notifyAll()
唤醒在此对象监视器上等待的所有线程。

String

toString()
返回该对象的字符串表示。

void

wait()
在其他线程调用此对象的 notify()方法或notifyAll()方法前,导致当前线程等待。

void

wait(long timeout)
在其他线程调用此对象的 notify()方法或notifyAll()方法,或者超过指定的时间量前,导致当前线程等待。

void

wait(long timeout, int nanos)
在其他线程调用此对象的 notify()方法或notifyAll()方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。

 

 

现在先看看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

  }

}

打印结果分别是:falsetruefalsefalsetrue。原因先不说,我们现在先看看”==”equals()方法的区别和联系。

 

==”和equals()方法的区别和联系

==”即相等性,相等性的比较有以下两点:

1) 对于原生数据类型来说,比较的是左右两边的值是否相等。

2) 对于引用类型来说,比较左右两边的引用是否指向同一个对象,或者说左右两边的引用地址是否相同。

 

equals()方法,该方法定义在Object类当中,因此Java中的每个类都具有该方法,对于Object类的equals()方法来说,它是判断调用equals()方法的引用与传进来的引用是否一致,即这两个引用是否指向的是同一个对象。对于Objectequals()方法来说,它等价于==

 

那么,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

  }

}

以上结果分别是truetrue。大家会奇怪,为什么会出现这样的结果,String不是继承了Object吗,特性怎么变得不一样?真正的原因其实是String类重写了父类Object类的equals()方法,通过看java源码可以得知。

那么我们进行总结:对于String类的equals()方法来说,它是判断当前字符串与传进来的字符串的内容是否一致。所以以后大家注意对于String对象的相等性判断来说,请使用equals()方法,而不要使用==

那么,我们来看看重写父类Objectequals()方法的普通类怎么实现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)  

}

}

发现StringBufferappend是完成字符串拼接,上面@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,等等。

所谓拆箱,就是跟装箱的方向相反,将IntegerDouble这样的引用类型的对象重新简化为值类型的数据。

下面关于包装类与原生数据类型互换代码。

 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);

  }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值