最近的工作是把几份C++代码翻译成java,不搞不知道,一搞吓一跳,真的很麻烦,C++和java的语法和其他细节差异太大了。下面就把遇到的一些差异整理总结一下:
1. 一维数组的定义:
C++:分为静态数组和动态数组,其中静态数组 int a[5],或int a[2]={1,2}
动态数组 int * a= new int[5],或 int * a = new int[2](1,2)
Java: 只有动态数组,所以其语法更类似C++的动态数组 int[] a = new int[5],[]代替*
如果要初始化值 int[]a={1,2}或者int[] a=new int[]{1,2}
总结:java定义数组的特点,=左项是类型+[]+变量名,而且注意[]中不能像C++那样带有数组大小,而且=右项的数组和指定初始值只能出现一个,为了方便好记,还是以int[] a = new int[5]和int[] a=new int[]{1,2}两种写法为主
2. 二维数组的定义:
C++:也是分成静态数组和动态数组,其中静态数组 int a[2][2]或int a[2][2]={{1,2},{3,4}},动态数组int (*a) [2]=new int[2][2]或int ** a=new int*[2]
Java:只有动态数组,语法跟一维数组一样,int[][] a=new int[2][2],或者int[][] a={{1,2},{3,4}}或者int[][] a =new int[][]{{1,2},{3,4}}
总结:java的二维数组定义注意点跟一维数组一模一样
3. 访问权限控制:
C++:存在权限访问控制块的概念,public:后续直到新权限访问控制块声明前定义的成员都是public访问控制权限
Java:不存在这种语法,每个成员都是单独声明访问控制权限的,跟上下文无关
4. Class的访问控制权限:
C++:Class关键字前面根本没有访问控制权限的概念,应该是任何其他文件都能访问的,跟java中的public Class应该是同样的效果
Java: Class关键字前面有访问控制权限的概念,声明为public Class的类才能被其他所有类访问并且必须和所在文件名同名,否则默认是包访问控制权限,只有包内的类能访问。
5. 构造函数(方法):
C++: 构造函数有初始化列表的概念,比如BillFileFormat::BillFileFormat(int (*fields)[2]) : _fields(fields){}
Java: 无构造方法初始化列表的概念,初始化动作直接在方法体内实现
总结:对于构造函数(方法)而言,有个很大的共同点,如果一个类没有实现构造函数(方法),则编译器会默认为该类生成一个无参默认构造函数(方法),如果类实现了构造函数,则编译器不再为其插入。另外如果父类的构造函数(方法)是带参数的,则子类必须实现构造函数并且显式调用父类的构造函数(方法),否则会出现编译错误,如果父类有无参(默认)构造函数(方法),则子类无需显示调用父类的构造函数(方法),编译器会自动插入调用父类无参(默认)构造函数(方法)。总而言之,不管是显式调用还是编译器帮忙插入,子类是必须调用父类的构造函数(方法)的,当然如果父类有无参(默认)构造函数(方法),我们就不需要显式编码,一切由编译器帮忙插入。另外java调用构造函数(方法)的语法是super(父类构造方法参数1,父类构造方法参数2,……)
6. 枚举类型:
C++:在C++中枚举的概念相对简单,使用也比较简捷,它更接近成员常量,而非类
// input is 0, output is 1, and appendis 2
enum open_modes {input, output,append};
--{}里面的各个值默认从0开始,自增1,为整数,某种程度而言它更像宏定义或者常量,编译是会直接被数值替换掉,唯一比较麻烦和让人误解的是对C++的enum变量的赋值,不能直接用整数赋值,必须用枚举成员或者枚举对象才能赋值,比如:open_modes a = 1//error,
open_modesb= input//ok。虽然网上找不到C++中枚举编译器处理后的底层实现,但是我认为C++的枚举更像是依赖于编译器处理替换成常量整数的一种语法规范,而不是真正意义上的类,跟宏定义或者常量更像,只不过外表披了一层类的外衣。
Java: 在java中枚举本质上是个类,只不过为了兼容C++枚举的概念,也起了enum的名字,但是实际使用上差别非常大,在java中enum 的语法结构尽管和 class 的语法不一样,但是经过编译器编译之后产生的是一个class文件,如上述C++的例子在java的实现编译后如下
publicclass open_modes extends java.lang.Enum{
public static final open_modes input;
public static final open_modes output;
public static final open_modes append;
new Enum<EnumTest>(" input ",0);
new Enum<EnumTest>(" output",1);
new Enum<EnumTest>(" append",2);
}
--可见本质是继承java.lang.Enum<E>的子类,枚举里面的成员其实是静态子类常量对象。进去java.lang.Enum源码里面可以发现
privatefinal String name;
privatefinal int ordinal;
protectedEnum(String name, int ordinal) {
this.name = name;
this.ordinal = ordinal;
}
--所以java中枚举本质是调用了Enum的构造方法把枚举成员名字和一个从0开始自增(编译器帮忙插入代码)整数作为传入参数,创建了静态子类常量对象。
总结:在C++中,枚举经常当整形常量成员使用,比如int a[append];相当于int a[2],根本没有顾及所属的枚举类型,而在java中,如果要实现这种用法就要int[] a =new int[open_modes.Input. ordinal()]