Java中的变参函数
众所周知,要在C/C++语言中定义参数个数可变的函数(后文简称变参函数)是一件挺麻烦的事,要么需要依赖一组宏,要么需要理解函数的调用约定然后写裸函数自己从栈中获取压入的参数,总之两者都不太方便。好在Java采用了一种更易于理解和使用的方法来定义变参函数。
对此,Java采用将数组的方式存储不定个数的变参。在需要在函数参数中使用变参类型时,只需使用“参数类型… 变参数组名”的方式即可,其中的”…”即表示参数个数可变。
public static void funcVarArgTest(String format, String... args) {
System.out.println("The format str is:" + format);
for (String str : args) {
System.out.println(str);
}
}
对此,结果是:
The format str is:This is a test
3333
22222
1111
javac在编译时,检测到了变参函数记号,会新建一个数组,将这些参数作为元素放入该数组。有时,为了考虑到传入参数的通用性,我们会采用这种写法:
public static void funcVarArgTest(String format, Object... args) {
//......
}
这样,该函数从第二个参数开始,就能接收任何数据类型了:
- 如果是原始数据类型,javac编译器将采用自动装箱(Auto-boxing)机制将其转为对应的Wrapper类
- 如果是类类型,则Object一定为其基类,所以实际执行的是向上转型
Java中的枚举类型
枚举背后的原理
- 创建枚举类使用的是 enum 关键字,且所创建的枚举类都是 java.lang.Enum 类的子类(这是一个抽象类)。
- 枚举类其实使用了泛型技术
Class Enum<E extends Enum<E>>
,其中E
表示枚举类型的名称。 - 枚举类中的每一个选项其实都是Enum类的一个实例,在定义后会调用
protected Enum(String name, int ordinal)
构造函数中,将每个值的名称都被转换成一个字符串,并且序数设置表示了此设置被创建的顺序。
枚举的使用方法
在Java中定义枚举类型方法和C/C++中较为类似:
public enum EnumWeekDays {
MON, TUE, WED, THU, FRI, SAT, SUN;
}
但其实,javac编译器会执行如下动作:
new Enum<EnumWeekDays>("MON",0);
new Enum<EnumWeekDays>("TUE",1);
new Enum<EnumWeekDays>("WED",2);
//......
使用上其实没有什么特别的:
enum EnumWeekDays {
MON, TUE, WED, THU, FRI, SAT, SUN;
}
public class CMain {
public static void main(String[] args) {
EnumWeekDays day = EnumWeekDays.FRI;
if (day == EnumWeekDays.FRI) {
System.out.println("Yeah, 周六准备加班吧哈哈");
}
else if (day == EnumWeekDays.SAT) {
System.out.println("周六加班发现bug没改完");
}
else if (day == EnumWeekDays.SUN) {
System.out.println("周日继续加班吧");
}
//......
}
}
一些成员方法
- toString() 返回枚举类型成员对应的字符串,就是在enum里定义的那个
- Enum Enum.valueOf(Class enumClass, String name) 返回对应name的枚举类成员
- int ordinal() 返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)
- compareTo(E other) 返回负数表明该枚举类型成员在传入的成员之前定义,0表示this==other,整数表示该枚举类型成员在传入成员之后定义。