黑马程序员_对象包装器、枚举类

-------android培训java培训、期待与您交流! ----------

对象包装器与自动打包:

所有的基本类型都有一个与之对应的类,通常这些类称为包装器(wrapper)。这些包装器拥有很鲜明的名字:Integer、Long、Float、Double、Short、Byte、Character、Void和Boolean(前6个类派生于公共的超类Number)。对象包装器类是不可变的,即一旦构造了包装器,就不允许更改包装器其中的值。同时,对象包装器类还是final,因此不能定义它们的子类。

假设想定义一个整型数组列表,而尖括号中的类型参数不允许是基本类型,也就是说,不允许写成ArrayList<int>,这里就要用到Integer对象包装器类,我们可以声明一个Integer对象的数组列表:

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

PS:由于每个值分别包装在对象中,所以ArrayList<Integer>的效率远低于int[]数组。因此,应该用它构建小型集合,其原因是此时程序操作的方便性要比执行效率更加重要。

 

Java SE 5.0的另一个改进之处是更加便于添加或获得数组元素,下面这个调用:

list.add(3);

将自动的变换成:

list.add(new Integer(3));

这种变换被称为自动打包(autoboxing)。

相反的,当将一个Integer对象赋值给一个int值时,将会自动拆包。也就是说,编译器将下列语句:

 int n = list.get(i);

翻译成:

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

甚至在算术表达式中也能够自动的打包和拆包。例如,可以将自增操作符应用于一个包装器引用:

Integet n = 3;
n++;

编译器将自动的插入一条拆开对象包的指令,然后进行自增计算,最后再将结果打入对象包内。

 

在两个包装器对象比较时一般调用equals方法。==运算符检测的是对象是否指向同一个存储区域,通常不会成立。

 

最后强调一下,打包和拆包是编译器认可的,而不是虚拟机。编译器在生成类的字节码时,插入必要的方法调用,虚拟机只是执行这些字节码。

 

使用数值对象包装器还有另外一个好处。Java类的设计者发现,可以将某些基本方法放置在一个包装器中,例如,将一个数字字符串转换成数值。

要想将字符串转换成整型,可以使用下面的语句:

int x = Integer.parseInt(s);

这里与Integer对象没有任何关系,parseInt是一个静态方法。但Integer类是放置这个方法的一个好地方。

 

参数数量可变的方法

从Java SE 5.0开始,提供了可以用可变的参数数量调用的方法(有时称为“可变参”方法)。

前面已经看到过这样的方法:printf。例如,下面的方法调用:

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

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

public class PrintStream
{
	public PrintStream printf(Stringfmt,Object…args)
	{
		return format(fmt,args);
	}
}

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

实际上,printf方法接收两个参数,一个是格式字符串,另一个是Object[]数组,其中保存这所有的参数(如果调用者提供的是整型数组或者其他基本类型的值,自动打包功能键把它们转换成对象)。

现在将扫描fmt字符串,并将第i个格式说明符与args[i]的值匹配起来。

编译器需要对printf的每次调用进行转换,以便将参数绑定到数组上,并在必要的时候进行自动打包:

System.out.printf(“%d %s”, newObject[] { new Integer(n) , widgets”});

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

public static double max(double…values)
{
	doublelargest = Double.MIN_VALUE;
	for(doublev : values) if(v > largest) largest = v;
	returnlargest;
}

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

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

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

PS:允许将一个数组传递给可变参数方法的最后一个参数。

 

枚举类

例:

public enumSize{SMALL,MEDIUM,LARGE,EXTRA_LARGE};

实际上,这个声明定义的类型是一个类,它刚好有4个实例,在此尽量不要构造新对象。

因此,在比较两个枚举类型的值时,永远不需要equals,而直接使用“==”就可以了。

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

enumSize
{
	SMALL(“S”),MEDIUM(“M”),LARGE(“L”),EXTRA_LARGE(“XL”);
	private Size(String abbreviation)
	{
		this.abbreviation =abbreviation;
	}
	public String getAbbreviation()
	{
		return this.abbreviation;
	}

	private String abbreviation;
}

所有的枚举类型都是Enum的子类。它们继承了这个类的许多方法。其中最有用的一个是toString,这个方法能够返回枚举常量名。例如:Size.SMALL.toString()将返回字符串“SMALL”。

toString()的逆方法是静态方法valueOf。例:

Size s = (Size)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.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值