Java核心卷 卷一 自我笔记 5.6继承-------对象包装器与自动装箱、枚举类和参数数量可变的方法

对象包装器与自动装箱

有的时候,我们需要将int这样的基本类型转换为对象。所有的基本类型都有一个与之对应的类。例如,Integer类对应基本类型int。通常,这些类称为包装器。这些对象包装器类拥有很明显的名字:Integer、Long、Float、Double、Short、Byte、Character、Void和Boolean。对象包装类是不可变的,即一旦构造了包装器,就不允许更改包装在里面的值。同时,对象包装器类还是final,因此不能定义它们的子类。
假设定义一个整数数组列表。而尖括号中的类型参数不允许是基本类型,也就是说,我们不能写成ArrayList<int>。这里就用到了Integer对象包装器类。我们先声明一个Integer对象的数组列表。

ArrayList<Integer> list=new ArrayList<>();

由于每个值分别包装在对象中,所以ArrayList<Integer>的效率远小于数组int [ ]。因此,在构造小型数组的时候,应该用int数组。

有一个很有用的特性,从而更加便于添加int类型的元素到ArrayList<Integer>中。下面这个调用:

list.add(3):

将自动地变换为:

list.add(Integer.valueof(3)):

这种变换称之为自动装箱。
相反,当将一个Integer对象赋给一个int值的时候,将会自动地拆箱。也就是说:

int n=list.get(i);

翻译成:

int n=list.get(i).intValue();

甚至在算术表达式中也能自动地装箱和拆箱。

大多数情况下,会容易有一种假象,即基本类型与它们的包装类型是一样的,只是它们的相等性不同。众所周知,==运算符也可以应用于对象包装器对象,只不过检测的是对象是否指向同一个存储区域,因此,下面的比较通常不会成立:

Integer a=1000;
Integer b=1000;
if(a==b){...}

然而,Java却有可能实现。如果将经常出现的值包装到同一个对象中,这个比较就有可能成立。所以,我们比较两个包装器对象通常用equals方法。

自动装箱需要注意的几点就是。首先,由于包装类可以引用为null,所以自动装箱有可能会抛出一个NullPointerException异常:

Integer n=null;
sout(2*n); //throws NullPointerException

另外,如果在一个条件表达式中混合使用Integer 和Double类型,那么Integer 值就会拆箱,提升为double,在装箱为Double:

Integer a=1;
Double n=2.0;
sout(true?a:n); //print 1.0

另外,装箱和拆箱是编译器认可的,而不是虚拟机。编译器在生成类的字节码时,插入必要的方法调用。虚拟机只是执行了这些字节码。
使用数值对象包装器的另一个好处就是可以将某些基本方法放置在包装器中,例如,将一个数字字符串转换为数值。
要想将字符串转换为整型,可以使用这条语句:

int x=Integer.parseInt("123");

这是一个Integer的静态方法,与Integer对象没有任何关系。
下面列出了Integer类中的重要方法:

  • int intValue( )
    以int的形式返回Integer对象的值
  • static String toString(int i)
    以一个新String对象的形式返回给定数值i的十进制表示
  • static String toString(int i,int radix)
    返回数值i的基于给定radix参数进制的表示
  • static int parseInt(String s)
  • static int parseInt(String s,int radix)
    返回字符串s表示的整型数值,给定字符串表示的是十进制的整数,或者是radix参数进制的整数
  • static Integer valueOf(String s)
  • static Integer value Of(String s,int radix)
    返回用s表示的整型数值进行初始化后的一个新Integer对象,给定字符串表示的是十进制的整数,或者是radix参数进制的整数。

枚举类

我们先定义一个枚举类:

public enum Size{SMALL,MEDIUM,LARGE,EXTRA_LARGE}

实际上,这个声明定义的是一个类,它刚好有4个实例,在此尽量不要构造新对象。
因此,在比较两个枚举的时候,不要用equals,用==;

如果需要的话,可以在枚举类型中添加一些构造器、方法和域。当然,构造器只是在构造枚举类常量的时候被调用。如下:

 public enum Size{
        SMALL("S"),MEDIUM("M"),LARGE("L"),EXTRA_LARGE("XL");
        private String a;
        private Size(String a){ this.a=a;}
        public String getAbbreviation(){return a;}
    }

所有的枚举类型但是Enum的子类。它们继承这个类许多方法。如下:
toString
这个方法能返回枚举常量名。例如,Size.SMALL.toString( )将返回字符串“SMALL”
valueOf
这是一个静态方法,例如:

Size s=Enum.valueOf(Size.class,"SMALL");

将s设置为Size.SMALL.

此外,每个枚举类型都有一个静态的values方法,它将返回一个包含全部枚举值的数组。例如:

Size values=Size.values():

返回包含元素Size.SMALL,Size.MEDIUM,Size.LARGE和Size.EXTRA_LARGE的数组。

ordinal方法返回enum声明中的枚举常量的位置,位置从0开始计数。例如:
Size.MEDIUM.ordinal()返回1。

我们以下面的这个程序演示枚举类型的工作方式。

public class qwe {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.println("Enter a size:(SMALL,MEDIUM,LARGE,EXTRA_LARGE)");
        String input = in.next().toUpperCase();
        Size size = Enum.valueOf(Size.class, input);
        System.out.println("size="+size);
        System.out.println("a="+size.getAbbreviation());
        if(size==Size.SMALL){
            System.out.println("ok");
        }
    }
}
     enum Size{
        SMALL("S"),MEDIUM("M"),LARGE("L"),EXTRA_LARGE("XL");
        private String a;
        private Size(String a){ this.a=a;}
        public String getAbbreviation(){return a;}
    }

参数数量可变的方法

在现在的版本中,提供了可以用可变的参数数量调用的方法(有时,叫做变参)。
我们之前已经使用过这样的方法:printf。例如,下面的方法调用:

System.out.printf("%d",n);
System.out.printf("%d %s",n,"widgets");

在上面的两条语句中,尽管一个调用了包含两个参数,另一个调用包含三个参数,但是它们调用的方法是同一个方法。
printf方法是这样定义的:

在这里插入代码片

这里的省略号…是Java代码的一部分,它表明这个方法可以接收任意数量的对象。

我们也可以自己定义可变参数的方法,并将参数指定为任意类型,甚至是基本类型。下面是一个简单实例:其功能为计算若干个数值的最大值。

 public static double max(double... values){
        double v = Double.NEGATIVE_INFINITY;
        for (double value : values) {
            if(value>v)
                v=value;
        }
        return v;
    }

可以像这样调用这个方法:

double m=max(3.1,40.0,-5);

编译器将new double[ ]{3.1,40.4,-5}传递给max方法。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值