同C/C++一样,JAVA也支持标准输入与输出,JAVA在System类中封装了三个静态属性System.in (标准输入), System.out(标准输出), System.err(标准错误输出)。同C/C++中IO处理不一样的,是JAVA中将IO都封装成不同的流,SDK的API已经打开了标准输入输出操作的数据流,因此,只需要对这些流进行操作,就可以直接输出输入数据,如System.out返回的是PrintStream直接可以打印出数据。而System.in是InputStream,可以使用任何读取操作。也可以使用java.util.Scanner类进行文本读取。
同C/C++不一样,JAVA中没有指针的概念,因此也就不存存字符串常量。JAVA有一个String类,但是操作方式有点像基本数据类型,String name =”hellowo”; String中有一个唯一使用的+进行重载后是连字符。注意连字符的优先级别是比运算符低。
同C/C++一样,JAVA中变量声明是有作用域范围的,但是因为JAVA是以类作为基本结构的。因此,不存在全局意义上的全局变量。变量最大范围是在类内。同样,JAVA也是分块,同一个块内同名变量只能声明一次,嵌入块之间不能声明同名变量。
同C/C++一样,JAVA中控制语句使用方式非常类似,没有GOTO语句,但GOTO作为关键字保留。if else也是使用短路模式。for语句同C++类似只是因为在JAVA中不再区分声明与实现的关系,所以for(int i=0;i<10;i++)是正确,而在C/C++中是不正确的。如下图,需要注意else if是从上到下执行,只要有一个满足条件,就跳出判断。其它像while,do while,switch等都是相同的。唯一同C++不一样的,因为没有GOTO语句,但是有LABEL,所以JAVA中使用Continue/break跳到LABEL处。
如下图所示:
JAVA同C/C++不一样,没有全局函数,全是类的成员函数,除了入口函数main之外。函数也无需在调用之前声明。函数直接在类中实现。函数的组成同C++一样,是由访问控制 返回类型 函数名称(参数)。函数的形参与实参之间一般都是传值。这里所说的传值,就是形参会复制一个实参的值。如果形参是基本数据类型,就是拷贝基本数据类型的值,如果是对象类型,拷贝的是对象的引用变量。返回值也一样,是拷贝一个新的。JAVA也支持函数的递归调用,但不支持C的扩展如函数内嵌。
同C/C++一样,JAVA也提供了一个单独的java.math.*包用来处理数学相关的,这其中就包括BigInteger/BigDecimal。通过可以实现任意精度的整数运算。
同C/C++一样,JAVA也支持数组,数组作用一个容器类,可以定义具有同一类型的固定数量的对象。长度固定。通过下标来访问。如下图所示
但同C/C++不一样的,JAVA的数组是new出来的。这个new不光是对象类型,所有类型都一样。因此,Array变量不在是分配在像C中的栈区,而是在堆区,这是一大区别。声明方式和初始化同C/C++类似。如下图所示,创建一个数组,先在方法区中声明引用变量,后在堆区开辟数组对象空间。
因为JAVA的数组是创建在堆上的对象,所以数组中存储对象如下图所示:
JAVA中数组的声明、初始化及赋值同C/C++类似。只是声明时需要注意,声明不能像C/C++中需要说明个数,JAVA中只需要简单声明如 int[] arr; 等创建时才给出具体的大小。赋值可以采用循环语句,输出使用for each 循环,后面这种循环结构是JDK5之后才有的特性。JAVA中二维数组同C中二维数组类似,二维数组可以看成一维数组的数组。只是这里数组元素也是new出来,不像C中是指针。
在数组之间进行拷贝,JAVA提供了一个静态方法java.lang.System.arraycopy或者Arrays中的sort方法进行排序,具体用法请参考JDKAPI文档。
同C/C++不一样的,JAVA是通过包名来确定命名空间的。因此,在JAVA中不需要单独设置命名空间。JAVA是以包名作为类实例存在的空间。通常包名是域名的倒写到代码源目录开始,如com.sina.weibo.app。这样有什么好处呢?一个比较容易的解决了命名空间问题,便于大规模开发,对不同公司的类库,也不用担心命名冲突的问题。第二因为是基于包组织代码的,因此,包空间也限制了访问权限。默认情况,JAVA的类和函数向外是四种访问权限,这些权限除了default不设置之外,春它三种是public,protect,private。这里需要注意,这三种才是真正的访问权限概念,同C/C++中用这些关键词进行访问加继承的混合用法。在JAVA中它就比较简单,因为这三个关键词不再参与类的继承方式,所以只代表访问权限。如果是PUBLIC,表明这个类,这个变量。这个函数可以被别的类访问,创建。如果是PRIVATE,则只能在当前类中进行访问。如果是PROTECT,则可以在同名包下访问。
因为这三个关键字只控制访问权限,不再参与继承方式,所以相对来说,更简单容易理解。因为JAVA是完全基于类的,所以对类的成员变量或者称之为域及成员函数,同C++是不一样。C++基于传统的声明与定义分开的原则,而在JAVA中是不存在这样的。JAVA中声明成员变量时直接就可以进行初始化,不需要非到构造函数中才能初始化。同样成员函数中除了静态函数之外也可以使用this和super这两个实例对象。
我们知道面向对象的基本初识是封装,也就是说构造一个对象尽量做到最小可访问。避免破坏对象内部结构。因此,声明变量时尽量私有化,通过提供公共方法对外访问。这样的好处再于避免对象实例成员变量未经检查的被重新赋值。一般在JAVA中推荐使用set/get成对使用。如下图所示,面向对象的一个基本概念就是隐藏内部状态,希望通过方法或者函数进行交互。
因为JAVA的面向对象比C++更进了一步,在JAVA中重载只会发生在类的成员函数之前。重载的规则也是不同的参数列表,这主要是指参数类型或者个数不同。重载与返回值无关。重载不发生在不同类之间。
JAVA与C/C++不一样,不存在引用与指针概念,因此,对函数参数只有一种传递方式就是传值。形参质实参的值,这个基本数据类型比较容易理解,对于类变量该怎样理解,在JAVA中也叫引用变量reference variable,但这个引用与C++中的引用不是同一个概念,在JAVA中对象它是不能直接操作的,因为JAVA没有指针概念,实例化对象都是通过new出来的,因此要访问对象,在JAVA中使用reference variable,有点类似于WINDOWS编程中的句柄概念。但它也不同于C++中reference,在C++中引用就是另一个变量的别名。是完全一样的。而在JAVA中引用不是这样的概念,它是堆上对象的一个索引。因此,在函数形参与实参的传递过程,是发生了拷贝的。因此同时作为引用变量的形参与实参是两个不同的索引,只是发生了值拷贝。
如上图结合下面的例子,可以看出来,dim与d虽然在传入开始是指向同一个堆中的对象,但是在方法区上是两个不同变量,它是可以重新指向另外的对象的。
在JDK5中向GCC学习引入了扩展可变参数函数,其声明方式void dostuff(char c,int… x){},这里有两点约束,就是可变参数一定是最后一参数,第二点就是一个函数只能有一个可变。实际上可变参数可以理解为一个数组。使用时也是按数组对象可变参数。
JAVA的构造函数同C++一样可以重载,缺省编译器会提供一下,如果不想使用缺省,可以覆盖,也可以重载出不同的形参的构造函数。但与C++不同的是不再有拷贝构造函数,为什么JAVA中不需要拷贝构造函数呢?我们相像一下JAVA中的对象它是不能直接访问的,它是通过引用变量。引用变量实际上是可以相等赋值的。因此无需拷贝构造函数。那怎么样表示两个引用变量指向的是同一个对象呢?通常可以通过重写Equal方式来设置特定的属性相等来标明是同一个对象。
同C++一样,JAVA提供了this和static关键字,这两个关键字用法同C++类似,不能同时使用。this在函数中使用代表对象实例,可用于构造函数中,但不可用于静态方法中。JAVA单独提供了一个新的关键字叫final用来限制类、域成员、方法等,用来表示只能赋值一次,不可再次更改。因为是只能赋值一次,因此对一个变量需要在定义时进行初始化。