zoukankan      html  css  js  c++  java
  • Java面向对象(二)

    包装类 (Wrapper Class)

    为了解决8种基本数据类型的变量不能当成Object类型变量来使用,Java提供了包装类概念。分别定义了它们相应的引用类型

    基本数据类型 包 装 类
    byte Byte
    short Short
    int Integer
    long Long
    char Character
    float Float
    double Double
    boolean Boolean

    在JDK1.5以前,把基本数据类型变成包装类实例,需要通过对应包装类的构造器来实现,8个包装类中,除了Character之外,还可以通过传入一个字符串参数来构建包装类对象。

      基本数据类型  -- 通过new WrapperClass(primitive)创建 --->  包装类对象

      包装类对象 -- 通过WrapperClass.xxxValue()方法 ---> 基本数据类型

      注意:上面的用法已经过时。

    JDK 1.5 提供了自动装箱 和 自动拆箱 功能。
    自动装箱:就是可以把一个基本数据类变量直接赋值给对应的包装类变量,或者赋值给Object变量(Object是所有类的父类,子类对象可以直接赋值给父类)
    自动拆箱:允许把包装类对象直接赋值给一个对象的基本数据类型变量。
    注意:进行自动装箱和自动拆箱时必须注意类型匹配。
    public static void main(String[] args) {
            // 直接将基本数据类型变量赋值给包装类变量
            Integer i = 5;
            Object obj = true;
            // 直接将包装类对象赋值给基本数据类型变量
            int it = i;
    
            if (obj instanceof Boolean) {
                // 先强制类型转换,再赋值
                boolean b = (Boolean) obj;
                System.out.println(b);
            }
        }
    包装类可以实现基本数据类型和字符串之间的转换:
        基本数据类型  -- 通过String.valueOf(primitive)转换 --->  String对象   (另一种方法:把基本数据类型变量和""进行连接运算,系统会自动把基本类型变量装换成字符串)
        String对象  --- 通过 WrapperClass.parseXxx()方法或利用包装类Xxx(String s)的构造器 ----> 基本数据类型
    public static void main(String[] args) {
            String intStr = "123";
            // 将字符串转换成基本数据类型变量
            int i = Integer.parseInt(intStr);
            int i2 = new Integer(intStr);
            System.out.println(i2);
    
            String floatStr = "3.1415";
            float f = Float.parseFloat(floatStr);
            float f2 = new Float(floatStr);
            System.out.println(f2);
    
            // 将基本数据类型变量转化成字符串
            String s = String.valueOf(f2);
            System.out.println(s);
    
            Integer a = new Integer(4);
            // 输出 true
            System.out.println(a > 3.0);
        }
    注意:虽然包装类型的变量是引用类型,但包装类的实例可以与数值类型的值进行比较,取出包装类实例的值来比较。
     
    特例:两个int类型的数组自动装箱成Integer实例,如果它的范围在-128~127之间,永远是引用cache数组中的同一个数组元素,所以相等;
            如果不在-128~127之间的整数自动封装成Integer实例,系统总是重新创建一个Integer实例,因此它们是不相等的。
    public static void main(String[] args) {
            Integer a = -1;
            Integer b = -1;
            // 输出 true
            System.out.println("a和b自动装箱后是否相等: " + (a == b));
    
            Integer e = 128;
            Integer f = 128;
            // 输出 false
            System.out.println("e和f自动装箱后是否相等: " + (e == f));
    
            Integer c = new Integer(2);
            Integer d = new Integer(2);
            // 包装类的实例实际上是引用类型,只有两个指向同一个对象才是true
            // 输出 false
            System.out.println("c和d包装类的实例是否相等:" + (c == d));
        }

    JDK1.7为所有的包装类提供了一个静态的compare(xxx val1, xxx val2)方法,来比较两个基本类型值的大小。

    处理对象

        Java对象都是Object类的实例,都可直接调用该类中的方法,这些方法提供了处理Java对象的通用方法。
        2.1  toString()
        Object类提供的toString() 方法总是返回该对象实现类的 ”类名 + @hashCode“ 值。hashCode是8位十六进制数字。
        如果用户需要自定义类能“自我描述”的功能,就必须重写Object类的toString()方法。
        2.2  == 和 equals 方法
        可以参考另一篇文章:http://www.cnblogs.com/FocusIN/p/6746759.html

    类成员

        static关键字修饰的成员就是类成员
        在java类里只能包含 成员变量、方法、构造器、初始化块、内部类(包括接口、枚举)5种成员。
        其中static可以修饰 成员变量、方法、初始化块、内部类(包括接口、枚举),以static修饰的成员就是类成员。
      类变量既可以通过类来访问,也可以通过类的对象来访问。当使用类的对象来访问类变量时,系统会在底层转换为通过该类来访问类变量。
        3.1 单例类
            如果一个类始终只能创建一个实例,则这个类被称为单例类。可以参考设计模式中的单例模式:http://www.cnblogs.com/FocusIN/p/6618811.html

    3.2 final修饰符

    final关键字可以修改 类、变量、方法,final关键字有点类似C#里面的sealed关键字,用于表示它修饰的类、方法和变量不可改变。

    final成员变量

      final修饰的成员变量必须由程序员显示地指定初始值。

      final修饰的类变量、实例变量能指定初始值的地方如下:

      类变量:必须在静态初始化中指定初始值声明该类变量时指定初始值,而且只能在两个地方的其中之一指定。

      实例变量:必须在非静态初始化块声明该实例变量构造器中指定初始值,而且只能在三个地方的其中之一指定。

    final局部变量

      系统不会对局部变量进行初始化,必须由我们现实初始化。因此使用final修饰局部变量,既可以在定义时指定初始值,也可以不指定初始值。

      如果在定义时没有定义初始值,则在后面的代码中可以对final变量赋初始值,但只能一次,不能重复赋值

      如果final修饰的的局部变量在定义时已经定义初始值,则后面代码不可以进行赋值。

    final修饰基本数据类型变量和引用类型变量的区别

      当使用final修饰基本数据类型变量时,不能对基本数据类型变量重新赋值,因此基本数据类型变量不能被改变。

      当对于引用变量时,它保存的是一个引用,final只能保证这个引用变量所引用的地址不会改变,即一直引用同一个对象,但这个对象完全可以发生改变。

    可执行“宏替换”的final变量

      对于final变量,不管是类变量、实例变量,还是局部变量,只要改变量满足以下三个条件,这个final变量就不再是一个变量,而是相当于一个直接量:

      1. 使用final修饰符修饰

      2. 在定义该final变量时指定了初始值

      3. 该初始值可以在编译时就被确定下来。

      综上,该变量本质上就是一个“宏变量”,编译器会把程序中所有用到该变量的地方直接替换成该变量的值。

      还有一种情况,如果被赋值的表达式只是基本的算术表达式或字符串连接运算,没有访问普通变量、调用方法,Java编译器同样会将这种final变量当成“宏变量”处理。

      例如: final int a = 5 + 2;      final String s = "你" + "好";

      注意: 对于final实例变量而言,只有在定义该变量时指定初始化值才会有"宏变量"的效果。

    final方法

      final修饰的方法不可被重写。但是还是可以被重载的。

      例如,Java提供的Object类中的getClass()方法,是final方法,就不可以被重写。

    final类

      final修饰的类不可以有子类。例如java.lang.Math类。

    不可变类

      指创建该类的实例后,该实例的实例变量是不可改变的。 不可变(immutable)

      Java提供的8个包装类和java.lang.String类都是不可变类,它们的实例的实例变量不可改变。

      如果需要创建自定义的不可变类,可遵循如下规则:

      使用private和final修饰符来修饰该类的成员变量

      提供带参的构造器,用来根据传入参数来初始化类里的成员变量

      仅为该类里的成员变量提供getter方法,不要提供setter方法,因为普通方法无法修改final修饰的成员变量。

      如果有必要,重写Object类的hasCode()和equals()方法。equal()方法根据关键成员变量来作为两个对象是否相等的标准,此外,还应该保证两个用equals()方法判断是否相等的对象的hashCode()也相等。

    缓存实例的不可变类

      不可变类的实例状态不可改变,可以很方便的被多个对象所共享。如果程序进程使用相同的不可变类实例,可以考虑缓存这种不可变类的实例。

    内部类

      类是一个独立的单元,在某些情况下,会把一个类放在另一个类的内部定义,这个定义在其他类内部的类就叫做内部类。(也叫作嵌套类)。包含内部类的类也被称为外部类

      从JDK1.1开始引入。

      内部类的作用:

      1. 提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类。

      2. 内部类成员可以访问外部类的私有数据,因为内部类被当成其外部类成员,同一个类的成员之间可以相互访问。但外部类不能访问内部类的实现细节,例如内部类的成员变量。

      3. 匿名内部类适合用于创建那些仅需要一次使用的类。

      

      从语法角度,定义内部类和外部类大致相同,内部类除了定义在其他类内部,还有以下不同:

      1. 内部类比外部类可以多使用三个修饰符:private、protected、static ------外部类不可以使用这三个修饰符。

      2.非静态内部类不能拥有静态成员。

      编译具有一个内部类的java文件,会产生两个class文件(注意内部类和外部类的数量)

      非静态内部类

      大部分时候,内部类都被作为成员内部类定义,而不是作为局部内部类。成员内部类是一种与成员变量、方法、构造器和初始化块相似的类成员;局部内部类和匿名内部类则不是类成员。

      成员内部类分为两种:静态内部类和非静态内部类。使用static修饰的成员内部类是静态内部类,反之,则为非静态内部类。

      静态内部类

      用static修饰的内部类,这个类属于外部类本身。

      外部类不能直接访问内部类的成员。使用静态内部类的类名作为调用者访问类成员;使用静态内部类对象作为调用者来访问实例成员。

      局部内部类

      放在方法里定义的内部类,叫做局部内部类。

      匿名内部类

      语法格式:

      new 实现接口() | 父类构造器(实参列表)

      {

        // 匿名内部类的类体部分

      }

  • 相关阅读:
    leetcode 78. 子集 JAVA
    leetcode 91. 解码方法 JAVA
    leetcode 75. 颜色分类 JAVA
    leetcode 74 搜索二维矩阵 java
    leetcode 84. 柱状图中最大的矩形 JAVA
    last occurance
    first occurance
    classical binary search
    LC.234.Palindrome Linked List
    LC.142. Linked List Cycle II
  • 原文地址:https://www.cnblogs.com/FocusIN/p/6339812.html
Copyright © 2011-2022 走看看