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 实现接口() | 父类构造器(实参列表)

      {

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

      }

  • 相关阅读:
    Cgroup学习笔记
    基于dubbo框架下的RPC通讯协议性能测试
    More about dubbo
    基于nginx tomcat redis分布式web应用的session共享配置
    基于开源Dubbo分布式RPC服务框架的部署整合
    More about Tair (NoSql)
    MySql Replication配置
    Memcached、Redis OR Tair
    基于淘宝开源Tair分布式KV存储引擎的整合部署
    关于TbSchedule任务调度管理框架的整合部署
  • 原文地址:https://www.cnblogs.com/FocusIN/p/6339812.html
Copyright © 2011-2022 走看看