Java——扩展概念(匿名内部类、包装类、装箱与拆箱、数据类型的转换)

时间:2022-07-25
本文章向大家介绍Java——扩展概念(匿名内部类、包装类、装箱与拆箱、数据类型的转换),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

本文讲解的扩展内容,包括:匿名内部类、包装类实现原理分析、装箱与拆箱、数据类型转换。

1、匿名内部类

匿名内部类,故名思意就是没有名字的内部类。匿名内部类有什么用?先看下面的一段简单代码:

【举例】:观察如下代码的问题

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        A a = new X();
        a.printA();
    }
}
interface A{
    public void printA();
}
class X implements A{
    @Override
    public void printA() {
        System.out.println("AAA");
    }
}

代码很简单,但是有这样一个问题,程序为接口A定义了一个子类X,但是此时的X子类只用了一次,是否有必要将其单独定义成一个类?设计显着比较冗余,不定义亦可。此时,可以利用匿名内部类解决,匿名内部类必须以抽象类或接口为前提进行使用。

【举例】:使用匿名内部类

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        A a = new A() {
            @Override
            public void printA() {
                System.out.println("AAA");
            }
        };
        a.printA();
    }
}
interface A{
    public void printA();
}

以上虽然实现了一样的功能,但是基本语法比较糟糕,程序结构也很混乱;目前,可以看懂匿名内部类即可,后续代码经验多了,这种手法自然就熟悉了。

2、包装类实现原理分析

Object类可以接收所有的引用数据类型,因为引用数据类型本质上就是对象,但基本数据类型不是对象,所以Object不能接收基本数据类型。那么将基本数据类型包装一下,就采用如下的代码结构:

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Int x = new Int(10);//将基本类型变为包装类
        Object obj = x; //对象转型
        System.out.println(x.intValue()*x.intValue());
    }
}

class Int{
    private int num;
    public Int(int num) {
        this.num = num;
    }
    public int intValue(){
        return this.num;
    }
}

以上代码,我们发现,若所有代码都这么设计,存在以下问题:

  • Java有8各基本数据类型,需要自己编写这8个基本类型;
  • 基本数据类型包装类不能直接参与数学计算;

正因为有这样的需求(参数统一需求),从JDK1.0开始提供了包装类,用户无需自己进行包装类的设计,JDK1.5后,解决了包装类参与数学计算的问题。8中基本数据类型包装类:

byte(Byte)、short(Short)、int(Integer)、long(Long)、float(Float)、double(Double)、char(Character)、boolean(Boolean)。

这8种包装类也分为两种类型:

  • 对象型(java.long.Object直接子类):Character、Boolean;
  • 数值型(java.lang.Number直接子类):Byte、Short、Integer、Long、Float、Double;

对于Number类,其本质上是一个抽象类:

public abstract class Number extends Object implements Serializable

Number类中有6个操作方法,这6个方法都属于拆箱方法:

  • 从包装类取出byte数据:public byte byteValue()
  • 从包装类取出int数据:public abstract int intValue()
  • 从包装类取出short数据:public short shortValue()
  • 从包装类取出long数据:public abstract long longValue()
  • 从包装类取出float数据:public abstract float floatValue()
  • 从包装类取出double数据:public abstract double doubleValue()

3、装箱与拆箱

基本数据类型与包装类之间的转换存在以下两个概念:

  • 装箱操作:将基本数据类型变为包装类;        --Integer类的构造方法:public Integer(int value)        --Double类的构造方法:public Double(double value)        --Boolean类的构造方法:public Boolean(boolean value)
  • 拆箱操作:将包装类中的基本数据类型取出;        --Number父类中定义的拆箱操作方法:xxxValue()方法

【举例】:以Integer与int为例

        Integer x = new Integer(10);
        int temp = x.intValue();

【举例】:以Double与double为例

        Double y = new Double(1.1);
        double temp = y.doubleValue();

所有的装箱与拆箱操作基本都是一个路子,以上方法都是在JDK1.5之前使用的,JDK1.5后提供了自动装箱与拆箱的支持:

        Integer x = 100; //自动装箱为类
        int y =x;//自动拆箱
        System.out.println(++x*10);//自动拆箱进行累加操作

实际上,这种自动装箱的机制,就可以使用Object接收基本数据类型了。

        Object obj =10; //转换:10自动装箱为Integer,其向上转型
        int temp = (Integer) obj;
        System.out.println(obj); //可以正常输出10
        System.out.println(temp);

以上的实验,我们可以看出,Object是所有数据类型都可以接收的!!

4、数据类型转换

包装类本身有个非常重要的功能,就是字符串转换为基本数据类型的操作。实际开发中,用户进行数据的输入操作,其类型就是String。

在包装类中提供转换方法,以常用的几个类型为主:

  • Integer类方法:public static int parseInt(String s);
  • Double类的方法:public static double parseDouble(String s);
  • Boolean类的方法:public static boolean parseBoolean(String s);

Character类中没有提供这样的方法,因为String类中有charAt()方法,直接选0索引即可。

【举例】:以Integer为例

        String temp = "100";
        int num = Integer.parseInt(temp);
        System.out.println(num);

但是,实际开发中需要注意,要进行这种转换,字符串必须全部由数字组成,否则会出现NumberFormatException错误;

另外,要注意关于判断比较的问题:

        String temp = "100";
        int num = Integer.parseInt(temp);
        Integer x1=100;
        Integer x2=new Integer(100);
        System.out.println(x1==num);//true
        System.out.println(x1==x2);//false

实际开发中,包装类使用比较多,所以,在进行==比较时,要使用eauals()方法最为保险,和String的情况类似。

【注意】:String要变为基本数据类型,可以使用包装类中的parseXxx()方法,基本数据类型转换为String呢?

  • 任何数据类型使用+ 与String连接都会转换为String类型,但是这种方法会产生垃圾;
  • 在String中有一组重载的valueOf()方法,可以避免垃圾产生,实际开发中都用这种;

String temp = ""+100;

String temp = String.valueOf(100);

5、总结

1)自动装箱与拆箱的特点;

2)Number类的定义及方法;

3)基本数据类型与String的转换;