Java基础  四

关键词: 包装类,Object类 ,String类,==与equals的区别,StringBuffer类,StringBuilder类

1.  java 8个基本类型的包装类

        大家都知道Java有8个基本类型(boolean、byte、short、int、long、float、double、char),Java是面向对象的编程语言,但这8个基本数据类型是不支持面向对象的编程机制的,即基本类型没属性、方法可以被调用。 有时某个方法需要object类型的参数,但实际需要的值却是2、3等数值,基本数据类型就不能满足这种条件了。Java为了解决8个基本数据类型的变量不能当成object类型变量使用的问题,Java为这8个基本类型提供了对应的包装类,通过这些包装类可以把8个基本类型的值包装成对象使用。

8个基本数据类型和包装类之间的对应
           基本数据类型       包装类
           byte                     Byte
           short                   Short
           int                     Integer [ˈɪntɪdʒɚ]
           long                     Long
           char                     Character
           float                     Float
           double                Double
           boolean              Boolean
        8个基本类型对应的包装类都是首字母大写。

基本类型与对应的包装类之间的转换
       例: int-->Integer
       /*
       int i = 1;
       // Integer in = new Integer(i); //通过Integer构造器将基本类型转换成包装类对象
       // Integer in = i; //从JDK1.5开始,JDK提供了自动装箱和自动拆箱共能,自动装箱:基本类型变量直接赋值给对应的包装类变量。自动拆箱:包装类对象直接赋值给对应的基本类型变量。
       // Integer in = Integer.valueOf(i); //通过Integer提供的静态方法将基本类型变量转换成对应的包装类变量。
       */
       例:Integer-->int
       /*
       Integer in = new Integer(1);
       // int i = Integer; //自动拆箱功能。
       // int i = Integer.intValue();
       */
       例:String-->Integer
       /*
       Srting s = "123";
       // Integer in = Integer.parseInt(s);
       // Integer in = new Integer(s);
       */
       例:Integer-->String
       /*
       Integer in = new Integer(123);
       int i = 123;
       // String s = in.toString();
       // String s = in+"";
       // String s = i + "";
       */

2.  Object类

       Object类是所有类、数组、枚举类的父类,也就是说,Java允许把任何类型的对象包括八大基本类型的任何一种赋值给Object类型的变量。当定义一个类时没有使用extends关键词时,则该类默认继承Object父类。

Object类提供的方法:
       boolean equals(object obj)
       判断指定对象与该对象是否相等。判断标准:两个对象应用变量是否指向同一地址。
       protected void finalize()
       当系统中没有引用变量引用到该变量时,垃圾回收器调用此方法来清理该对象的资源。
       String toString()
       返回该对象的符号表示 ,当我们使用System.out.println方法输出一个对象或某个对象和字符串连接时,系统会自动调用toString方法返回该对象的字符串表示。Object的toString方法返回”运行时类名@16进制hashCode值“(hashCode是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值)格式的字符串,但很多类都重写了Object类的toString方法,用来描述对象的所有状态信息。
       除此之外Object还提供了其他的几个方法。

3.  String类

       是不可变类!即一旦一个String对象被创建以后,包含在这个对象中的字符序列是不可改变的(不能对原有的数据进行插入,删除部分,但是可以在末尾添加),直至这个对象被销毁。
       toString方法——重写了Object类的toString方法,使之显示String对象中的内容。

例:toString方法的重写
       /*
       class People{
       private String name;
       public People(String name,int age){
       this.name = name;
       this.age = age;
       }
       public String toString(){
       return "姓名:"+name+",年龄:"+age;
       }
       }
       public class Test{
       public static void main(String [] args){
       People p = new People("李华",18);
       System.out.println(p); //当输出p对象时,实际上p对象会调用toString方法,输出的是toString的返回值。注意!只有当输出时才会自动调用toString方法。
       System.out.println(p.toString());
       People p2 = p;
       System.out.println(p == p2);//输出true,不会调用toString方法。
       }
       }
       */
输出结果:
       姓名:李华,年龄:18
       姓名:李华,年龄:18

例:字符串常量的理解
       String s = ”I”+“Love”+“Java”;
       上面的程序除了使用了3个字符串常量(临时变量)之外,还会额外生成2个字符串常量(临时变量),其中”I“和”LOVE”生成了“ILOVE”保存在内存中,接着“ILOVE”与“Java”生成了“ILOVEJava”字符串并将它赋给s变量。因为String是不可变的所以会额外产生很多临时变量,这些临时变量都存储在JVM中的常量池中。
       常量池:是指在编译期被确定,并被保存在以编译的.class文件中的一些数据。它包括关于类、方法、接口中的常量,同时也包括了字符串常量。

4.  ==与equals的区别

       Java程序中测试两个变量是否相等有两种方式,一种是利用==运算符,另一种是利用equals方法。

==判断两个变量是否相等
       如果两个变量是基本类型的变量,且都是数值型,则只要两个变量的值相等,使用==判断将会返回true。
       如果两个变量是引用变量,必须他们指向同一个对象时(也就是判断内存地址是否一致),==判断才会返回true。
例:
       /*
       int i = 1;
       int j = 1;
       System.out.println(i==j); //将输出true
       float f = 1.0f;
       System.out.println(i==f); //将输出true
       i = 65;
       char ch = 'A';
       System.out.println(i==ch); //将输出true
       String s1 = new String("haha");
       String s2 = new String("haha");
       System.out.println(s1==s2); //将输出false
       String s3 = s1;
       System.out.println(s1==s3); //将输出true
       */

例:【转】String 的经典笔试题一
       String s = new String("abc");
       String s1 = "abc";
       String s2 = new String("abc");
       System.out.println(s == s1);
       System.out.println(s == s2);
       System.out.println(s1 == s2);
       请问 前面三条语句分别创建了几个对象,分别是什么.后面的输出分别是什么?
       答:
       (1)String s = new String("abc"); 这句,创建了两个对象,其内容都是"abc".注意,s不是对象,只是引用变量.只有new生成的才是对象. 创建的流程是,首先括号里 的"abc"先到常量池里看有没"abc"这个对象,没有则创建这个对象。所以这里就在常量池中创建了一个"abc"对象。然后 通过new语句又创建了一个"abc"对象,而这个对象是放在内存的堆里,这里的s指向堆里的对象.
       (2) String s1 = "abc"; 这条语句,s1当然还是引用。后面的"abc",其实就是上面括号里的"abc".执行的是相同的操作.即 在常量池里查找有没"abc"这个对象.没有则创建一个,很显然,第一条语句已经创建了一个"abc".所以这条语句没有创建对 象,s1指向的是常量池中的"abc"
       (3)String s2 = new String("abc"); 这条语句,其实和第一条是一样的,但是,因为第一条已经在常量池中创建了"abc"这个对象,所以,这条语句创建了一个对象.s2指向的是堆里 的"abc"。注意,虽然内容都是"abc",s与s2表示的是不同的对象
        (4)下面的三个==判断.(注意,==永远是判断内存地址是否相等) s与s1,一个指向堆里的对象,一个指向常量池里的.很明显是不同的对象.s与s2.上面说了,虽然都是指向堆里的对象,内容也是"abc",但是也不 是相同的对象.s1与s2.一个指向常量池,一个指向堆.也不是相同的对象.所以三个都返回false.

例:【转】String 的经典笔试题二
       String s = new String("abc");
       String s1 = "abc";
       String s2 = new String("abc");
       System.out.println(s == s1.intern());
       System.out.println(s == s2.intern());
       System.out.println(s1 == s2.intern());
       System.out.println(s1 == s2);
       求最后输出是什么?
       答:
       最后的答案是 false false true false。
       intern()方法就是扩充常量池的一个方法;当一个String实例s调用intern()方法时,Java查找常量池中是否有相同的字符串常量,如果有,则返回这个字符串常量的引用但不会更改s的引用,如果没有,则在常量池中增加一个等于s的字符串常量并返回它的引用但不会更改s的引用;
       这样就很容易理解了。s1.intern返回的是常量池里的"abc"对象.与s这个堆里的对象肯定不同,返回false.同理,s与s2.intern()也肯定不 同,返回false.第三个,s1与s2.intern().其中s2.intern()返回的是常量池中的"abc"对象,而s1也是指向常量池中 的"abc"对象.所以返回的是true:对于最后的一个语句,虽然上一条语句s2调用了intern方法,但是并没有改变s2的引用s2仍指向堆里的对象,s1指向的是常量池的对象,故返回的是false

例:【转】String 的经典笔试题三
       String hello = "hello";
       String hel = "hel";
       String lo = "lo";
       System.out.println(hello == "hel" + "lo");
       System.out.println(hello == "hel" + lo);
       System.out.println(hello == hel + lo);
       求输出的结果
       答:
       最后答案是 true false false
       首先,上面已经说明了,hello hel lo这三个都是指向常量池中的对象。
       现在我们考虑"hel" + "lo" 按照内容来说,两个相加也就是"hello".这个时候,这个会返回常量池中的"hello"对象.所以,hello == "hel" + "lo" 返回的是true .
       而"hel" + lo 虽然内容也是"hello",但是它将在堆里面生成一个"hello"对象,并返回这个对象。所以这里的结果是false。
       同理hel + lo 虽然内容也是"hello",但是它也会在堆里面生成一个"hello"对象,并返回这个对象。所以这里的结果是false

equals
       equals 方法也是Object类提供的一个实例方法,所有Java对象都可调用equals方法。
       Object类判断两个对象是否相等的标准与==相同,只有两个变量指向同一个对象时才会返回true。
       例:
       /*
       class A{
       }
        public class B{
       public static void main(String[] args){
       A a1 = new A();
       A a2 = new A();
       A a3 = a2;
       System.out.println(a1.equals(a2)); //将输出false
       System.out.println(a1.equals(a3)); //将输出false
       System.out.println(a3.equals(a2)); //将输出true
       String s1 = new String("asd");
       String s2 = new String("asd");
       String s3 = "asd";
       System.out.println(s1.equals(s2)); //将输出true
       System.out.println(s1.equals(s3)); //将输出true
       System.out.println(s3.equals(s2)); //将输出true
       }
       }
       */
       上例中String变量中s1,s2都是通过new创建过的实例,两个变量引用的地址是不一样的,那为什么会相等呢?
       这是因为String重写了equals对象,提供了判断两个变量相等的标准。(判断两个字符串相等的标准是:只要两个字符串所包含的字符序列相同,则通过equals比较将返回true)。
       所以当我想通过equals判断我们自定义的对象是否是相同的,那我们得重写equals方法,给出我们的判断标准。

4.  StringBuffer类

       StringBuffer是一个可变的字符串,当一个StringBuffer被创建后,通过StringBuffer提供的append(末尾添加)、insert(插入)、reverse(翻转)、setCharAt(设置指定位置的字符)、setLength(设置字符串长度)等方法可以改变这个这个字符串对象。
       注意:当setLength的长度小于字符串的长度时,会截取掉末尾多余的不封。
如:
       String s = “hellojava”
       s.setLength(5); //s会变为“hello”

5.  StringBuilder类

       和StringBuffer基本类似。不同的是,StringBuffer是线程安全的,而StringBuilder则没有实现线程安全功能,但性能略高。

我是续!快点我!

尊重原创,写博不易,转载请注