编程语言哪家强,不是Java就是C++:Java与C++语法对比分析

Java
221
0
0
2023-11-07

JAVA 相对于 c++ 而言属于上层语言,因此一般用于应用层系统的开发,比如 java 最擅长的web服务端开发,而c++偏向底层一些,更合适做一些底层的东西,比如JAVA的 jvm 就是c++语言开发的,而且JAVA在算法方面相比c++性能稍微差一些。

目录:

1 语言源起

C++继承自C,偏向底层、具有灵活性、效率优先考量的观念,但在数据和代码组织方面,在 面向过程 的基础上实现了面向对象,提高了代码的安全性、可扩充性。在引入STL标准库时,同时引入了模板和泛型的语法机制。

Java希望降低C++的复杂性,进一步提升代码的安全性,如不使用指针,使用更安全和简单的引用,不使用多继承,使用实现多个接口,为了安全与简便,选择牺牲一定性能,使用了自动垃圾回收(GC,Garbage Collection)机制,为跨平台使用 字节码 编译与JVM解释执行。

C哲学:效率第一,用函数实现模块化;

C++哲学:效率第一、安全第二、代码利用与扩展第三(用类来组织数据和代码);

Java哲学:一切皆对象,对象皆源于Object,对象皆堆内存引用,对象皆初始化。

2 平台问题

应用程序运行于平台(硬件(指令集)系统+操作系统(API))之上,应用程序的编写自然要考虑运行的平台及跨平台的问题。

C++针对不同平台编写和使用不同的编译器,直接编译到机器码。当编写非图形界面的服务器端程序时,要在语法上考虑跨平台性,当编写图形界面程序时,要编写不同平台的版本,或使用跨平台的 QT 库。

Java是使用编译器( Javac .exe)将源程序(.java文件)编译为字节码(. class文件 ),在不同的平台上安装JVM,字节码通过解释器(java.exe)在JVM上解释执行,所以Java具有跨平台性。

3 宏与预编译

Java不使用宏,代码也无须预编译。( MFC 考虑效率,使用了大量的宏来实现消息映射,而不是使用 虚继承 的多态。)

Java通过import引用类库,同时引入了命名空间。Java只是使用关键字final来定义常量。

Java 用包代替了命名空间。由于将所有东西都置入一个类,而且由于采用了一种名为“封装”的机制,它能针对类名进行类似于命名空间分解的操作,所以命名的问题不再进入我们的考虑之列。数据包也会在单独一个库名下收集库的组件。我们只需简单地“import”(导入)一个包,剩下的工作会由编译器自动完成。

Java 已取消的一种特性是C 的“条件编译”,它允许我们改变参数,获得不同的行为,同时不改变其他任何代码。Java 之所以抛弃了这一特性,可能是由于该特性经常在C 里用于解决跨平台问题:代码的不同部分根据具体的平台进行编译,否则不能在特定的平台上运行。由于Java 的设计思想是成为一种自动跨平台的语言,所以这种特性是没有必要的。
然而,条件编译还有另一些非常有价值的用途。一种很常见的用途就是调试代码。调试特性可在开发过程中使用,利用包(package)来模仿条件编译的概念。

4 基本类型相关

C++继承了C的灵活性和对效率放在第一位的观念,Java强调统一规范与安全放在首位考量的思路。(Java统一规范的语法让其编辑器实现语法提示的编码更为简单和高效。)

Java对每种数据类型都分配固定长度,Java的 long 无论是32位还是64位系统,都是64bit。而在 C语言 和C++语言中,对于不同的平台,同一个数据类型分配不同的字节数。这造成了C语言的不可移植性,而Java则具有跨平台性(平台无关性)。

Java的 char 是16bit,使用 unicode 编码。

C++

Java

变量只能以字母和下划线开头

int $var = 3; // Java还可以以$开头

bool b = true;

boolean b = true;

bitset <8> bs; // STL <bitset>

int bit = 0b01011;

String str;// 声明与定义

String declar; // only reference declaration

declar = new String(“abc”); // refer from heap

time_t first = time(NULL);

long startTime = System.currentTimeMillis();

System.out.println(startTime);

Java对类型的检查和要求在Java 里变得更苛刻。例如:

条件表达式只能是boolean(布尔)类型,不可使用整数。
必须使用象X+Y 这样的一个表达式的结果,不能仅仅用“X+Y”来实现“副作用”。

在C语言和C++语言中,可通过指针进行任意的类型转换,常常带来不安全性,而在Java中,运行时系统对对象的处理要进行类型相容性检查,以防止不安全的转换。

在 C 和 C++ 中有时出现数据类型的隐式转换,这就涉及了自动强制类型转换问题。例如,在 C++ 中可将一 浮点 值赋予整型变量,并去掉其尾数。Java 不支持 C++ 中的自动强制类型转换,如果需要,必须由程序显式进行强制类型转换。

 // Java
int a =.0; // error
 Float  = 2.0; // error 

Java 取消了 C/C++ 中的结构和联合。

Java三种类型:

Java的哲学是一切皆对象,但为了效率考虑,保留了基本类型,但方法需要对象引用类型时,可以考虑基本类型的包装类型。

1 primitive types : boolean, byte , char, double, float, int, long, short . 基本类型用作类属性(状态)或方法的局部变量(保存在栈内存)。不能用做集合类参数类型,如不能使用 Vector <int>,但可以是Vector< Integer >。

2 reference types : A class type, interface type, or array type, such as String, Charge, Comparable, or int[]. A variable of a reference type stores an object reference, not the data-type value itself. 集合类参数类型使用引用类型,如Vector<Integer>。

3 wrapper types : built-in reference types,A reference type corresponding to one of the primitive types, such as Boolean, Btye, Character(char), Double, Float, int(Integer), Long, Short. Java automatically converts between an object from a wrapper type and the corresponding primitive data-type value—in assignment statements, method arguments, and arithmetic/logic expressions.

 Integer xx =; // Autoboxing (int -> Integer)
int aa = xx;  // Unboxing (Integer -> int) 

Java对于所有不属于primitive类型的对象,都只能通过new 命令创建(保存在堆内存)。和C++不同,Java 没有相应的命令可以“在堆栈上”创建不属于primitive类型的对象。所有primitive类型都只能在堆栈上创建,同时不使用new 命令。所有primitive类都有自己的“封装(器,wrapper)”类,所以能够通过new 创建等价的、以内存“堆”为基础的对象(primitive类型数组是一个例外:它们可象C++那样通过集合初始化进行分配,或者使用new)。

编程语言哪家强,不是Java就是C++:Java与C++语法对比分析

Java 会用 d 或 D 表示一个直接数字是 double 类型的 浮点数 ,比如 200.0d 或(200.0D),但是 C++ 不支持,因为 C++ 默认一个浮点型的直接数字就是 double 类型。

C++ 用字面量符号 f 或 F 表示一个直接数字是 float 类型浮点数,比如 250.1 f(或 250.1F),这一点 Java 也是一样的。

C++ 用字面量符号 l 或 L 表示 long,用 UL 表示 unsigned long。

5 函数相关

在 C 中,代码组织在函数中,函数可以访问程序的 全局变量 。C++ 增加了类,提供了类算法,该算法是与类相连的函数,称为成员函数,C++成员函数可以被 static 修饰,称为静态成员函数。

由于 C++ 仍然支持 C ,所以不能阻止 C++ 开发人员使用全局函数,结果全局函数和成员函数混合使用使得程序比较混乱。

Java 没有全局或外部函数,作为一个比 C++ 更纯的面向对象的语言,Java 强迫开发人员把所有例行程序包含在类中,事实上,用方法实现例行程序可激励开发人员更好地组织编码。

Java的成员函数称为instance方法,如果其用static修饰,称为类方法,可以直接由类名调用。

C++

java

static member functions

non-static member functions

static methods(class methods or functions)

instance methods

Java不支持缺省方法参数,而C++支持缺省函数参数。

参数传递:

C++

Java

pass by value

pass by pointer

pass by referecne

pass by value

① primitive types

② reference types

③ wrapper types

主函数:

C++

Java

int main(int argc, char*args[])

public static void main(String[] args)

args[0]: not program self

Java 不存在“嵌入”(inline)方法。 Java 编译器 也许会自行决定嵌入一个方法,但我们对此没有更多的控制权力。在Java 中,可为一个方法使用final 关键字,从而“建议”进行嵌入操作。然而,嵌入函数对于C++的编译器来说也只是一种建议。

由于Java 在某些场合可能显得限制太多,所以有时不愿用它执行象直接访问硬件这样的重要任务。Java 解决这个问题的方案是“固有方法”(native method),允许我们调用由其他语言写成的函数(如支持C 和C++)。

6 类相关

Java的全部数据和方法都定义在类中,没有全局变量或外部变量一说,因此也无须域操作符“::”。

C++和Java的基本构成:

C++

Java

① declaration;

② global data;

③ data type definition;

④ function;

⑤ class;

Everythis is class

(include interface,

abstract class)

Java 中不必进行提前声明。若想在定义前使用一个类或方法,只需直接使用它即可——编译器会保证使用恰当的定义。所以和在C++中不同,我们不会碰到任何涉及提前引用的问题。

每个编译单元都必须有一个以.java 结尾的名字。而且在编译单元的内部,只能有一个公共(public)类(其它class类不能用public修饰,实现隐藏),它必须拥有与文件相同的名字(包括大小写形式,但排除.java 文件扩展名,可能(但并常见)有一个编译单元根本没有任何公共类。此时,可按自己的意愿任意指定文件名。)。每个编译单元有一个公共接口的概念是由那个公共类表达出来的。

若在一个文件的开头使用下述代码:
package mypackage;
那么 package 语句必须作为文件的第一个非注释语句出现。该语句的作用是指出这个编译单元属于名为mypackage 的一个库的一部分。或者换句话说,它表明这个编译单元内的public 类名位于mypackage 这个名字的下面。如果其他人想使用这个名字,要么指出完整的名字,要么与mypackage 联合使用import 关键字(使用前面给出的选项)。注意根据Java 包(封装)的约定,名字内的所有字母都应小写,甚至那些中间单词亦要如此。
作为一名库设计者,一定要记住package 和import 关键字允许我们做的事情就是分割单个全局命名空间,保证我们不会遇到名字的冲突。

Java不在所有类之外定义全局变量,而是在某个类中定义一种公用静态的变量来完成全局变量的功能。

C++ 的类成员访问控制采用分节控制,用 public: protected: 作为分节的标志,如果没有分节标志的类成员,则是默认的 private : 控制。 Java需要逐个成员修饰。

Java不是象C++那样控制声明代码块,而是将访问限定符(public,private 和protected)置入每个类成员的定义里。若未规定一个“显式”(明确的)限定符,就会默认为“友好的”(friendly )。这意味着同一个包里的其他元素也可以访问它(相当于它们都成为C++的“friends”——朋友),但不可由包外的任何元素访问。类——以及类内的每个方法——都有一个访问限定符,决定它是否能在文件的外部“可见”。private 关键字通常很少在Java 中使用,因为与排斥同一个包内其他类的访问相比,“友好的”访问通常更加有用。然而,在 多线程 的环境中,对private 的恰当运用是非常重要的。Java 的 protected 关键字意味着“可由继承者访问,亦可由包内其他元素访问”。注意Java 没有与C++的protected 关键字等价的元素,后者意味着“只能由继承者访问”。

在Java 中,类定义采取几乎和C++一样的形式。但没有标志结束的 分号 。没有class foo 这种形式的类声明,只有类定义。Java的构造机制与C++类似,但没有 复制构造函数 ,因为所有自变量都是按引用传递的。

 // c++
class Shape{
    int m_color;
    public:
Shape(int color=){m_color = color;}
    virtual double Area() =;
};

abstract class Shape{
    private int _color;
    Shape(){
        _color =;
    }
    Shape(int color){
        _color = color;
    }
    abstract double area();
} 

Java的成员默认为package作用域,C++默认为private。

内部类:

C++

java

no right to access outer member

has an implicit reference to the outer class object

在C++中,对类进行嵌套有助于隐藏名称,并便于代码的组织(但C++的“命名空间”已使名称的隐藏显得多余)。Java 的“封装”或“打包”概念等价于C++的命名空间,所以不再是一个问题。Java 1.1 引入了“内部类”的概念,它秘密保持指向外部类的一个句柄——创建内部类对象的时候需要用到。这意味着内部类对象也许能访问外部类对象的成员,毋需任何条件——就好象那些成员直接隶属于内部类对象一样。这样便为 回调 问题提供了一个更优秀的方案——C++是用指向成员的指针解决的。由于存在前面介绍的那种内部类,所以Java 里没有指向成员的指针。

7 对象的创建与回收

Java的对象全部创建在堆上。C++的对象可以创建在全局区、栈区、堆区。

Java GC程序以线程方式在后台运行的,利用空闲时间工作。

 // java
Circle mc; // 单纯的引用类型,并不是栈上对象
mc = new Circle(); // 堆上对象,并自动初始化,自动回收
// ……
 finalize (); // java回收垃圾的时间不确定,会调用finalize()在回收前做一些善后操作

// C++
Circle c; // 全局或栈上对象,自动回收
Circle *mc = new Circle(); 
// ……
delete mc; 

finalize()是由垃圾收集器调用的,而且只负责释放“资源”(如打开的文件、套接字、端口、URL 等等)。

8 this指针与引用

C++的this指针与Java的this引用稍有区别:

 // C++
class Circle{
    double radius;
    public:
   Circle(){
        this->radius =.0;
   }    
   Circle(double radius){
        this->radius = radius;
   }
   double getRadius(){
       return radius;
   }
    double Area(){
        return this->getRadius()*this->radius*.14159;
    }
};// this指针不能访问静态属性和静态函数

// Java
class Circle{
    private double radius;
    public Circle(){
        this(.0); // 调用其它 构造函数 
    }
    public double getRadius(){
        return radius;
    }
    public Circle(double radius){
        this.radius = radius;
    }
    public double Area(){
        return this.radius*this.getRadius()*Math.PI;
    }
} 

9 数组相关

C++的数组有静态数组、动态数组、封装的vector容器。

Java的数组属于类,也有Vector容器,ArrayList。

C++的数组名不能做左值,在不同的上下文中有不同的含义,与操作符“sizeof”或“&”使用时表示数组整体,其它上下文中表示数组首元素及类型。

Java的数组名可以做左值被赋值,但只是引用(引用本身(一个地址或指针)保存在栈,引用指向的内容保存在堆)本身的赋值,而不是引用指向内容的赋值。同样的,数组做函数参数或返回值也是一个引用。

(C++的引用可以理解为一个由编译器实现了解引用的具有常量性质的指针,Java的引用可以理解为一个指向复合数据(数组和对象)的基指针,其本身无须解引用,指向常量时自动解引用。)

 //C++
int arr[3][5]; // 未初始化
int arr[3][4] = {0}; // 第一个元素按值初始化,剩下的元素初始化为0
int arr[][2]={1,2,3,4,5,6}; // 静态初始化

// Java
int[][] arr;  // 只是声明,一个引用声明,因为不能在栈上建立数组空间
int[][] arr = new int[3][5]; // 有默认初始化为0值, arr0是一个引用
int[][] arr = {{1,2},{3,4},{5,6}}; 

Java have bounds checking, no pointer arithmetic.

C++

java

int arr[];

int[] arr; or int arr[];

int *arr = new int[25];

int[] arr = new int[25];

vector<int> arr[25];

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

// the angle brackets cannot be a primitive type

10 对象数组

Java的对象数组是一个引用数组(堆空间,数组名作为引用本身保存在栈空间),再由每一个引用指向一个对象(也是堆空间),有点类似于C++的指针数组。

 // java
Circle[] cArr = new Circle[]; // 引用变量数组
// cArr是引用类型,本身保存在栈空间,然后建立了个引用类型(堆空间),会自动初始化为null
// cArr[i] 还是要进一步new Circle()以指向具体的Circle对象

//C++
Circle cArr[];
Circle *cArr[10]; // 相对于Java的引用变量数组 

11 继承相关

Java 采用了一种单根式的分级结构(所有对象都是从根类Object 统一继承)。而在C++中,我们可在任何地方启动一个新的继承树,所以最后往往看到包含了大量树的“一片森林”。在Java 中,我们无论如何都只有一个分级结构。尽管这表面上看似乎造成了限制,但由于我们知道每个对象肯定至少有一个Object 接口,所以往往能获得更强大的能力。C++目前似乎是唯一没有强制单根结构的唯一一种OO语言。

C++继承使用操作符“:”,默认为private继承,可以显示声明public、protected、private继承方式。

 // C++
class Shape{
    int m_color;
    public:
Shape(int color=){m_color = color;}
    virtual double Area() =;
};
class Circle:public Shape{
    double m_radius;
    public:
    Circle(double radius,int color=):Shape(color),m_radius(radius){}
    virtual double Area(){
        return.14159*m_radius*m_radius;
    }
}; 

Java继承使用关键字extends,默认为public继承。Java使用super语句来构造父类构造函数的调用链。

 abstract class Shape{
    private int _color;
    Shape(){
        _color =;
    }
    Shape(int color){
        _color = color;
    }
    abstract double area();
}
class Circle extends Shape{
    private double _radius;
    public Circle(double radius,int color){
        super(color);
        this._radius = radius;
    }
    public Circle(double radius){
        super();
        this._radius = radius;
    }
    double area(){
        return Math.PI * Math.pow(_radius,);
    }
} 

Java的protected类的作用域为子类或package。

C++支持多继承,Java支持单继承,通过implements interfaces(实现多个接口)可以间接实现多继承。

Java 提供了一个interface 关键字,它的作用是创建抽象基础类的一个等价物。在其中填充抽象方法,且没有数据成员。这样一来,对于仅仅设计成一个接口的东西,以及对于用extends 关键字在现有功能基础上的扩展,两者之间便产生了一个明显的差异。不值得用abstract 关键字产生一种类似的效果,因为我们不能创建属于那个类的一个对象。一个abstract (抽象)类可包含抽象方法(尽管并不要求在它里面包含什么东西),但它也能包含用于具体实现的代码。因此,它被限制成一个单一的继承。通过与接口联合使用,这一方案避免了对类似于C++虚拟基础类那样的一些机制的需要。为创建可进行“例示”(即创建一个实例)的一个interface(接口)的版本,需使用implements 关键字。它的语法类似于继承的语法。
接口中定义的字段会自动具有static 和final 属性。它们不能是“空白final”,但可初始化成非常数表达式。

12 多态相关

Java默认多态,可以使用final关键字修饰来避免多态。

C++使用virtual修饰成员函数来实现多态。

13 指针与引用

C++没有公共基类,但可以转换为void指针。

java的对象定义使用new运算符,一经定义返回的就是引用,无须 “&”声明。

Java的引用与C++的指针和引用都表示一个特殊的地址,但其类型含义、实现及使用场景各不相同。

C++引用在创建时必须进行初始化,而且不可重定义到一个不同的位置。但Java 引用并不一定局限于创建时的位置。它们可根据情况任意定义,这便消除了对指针的部分需求。

Java的引用,不使用算术运算,其赋值、比较是地址的操作。引用不能被破译为原始地址,也不允许进行危险的更改。

 // Java
private class Node {
    private String item;
    private Node next;
} 

Java没有指针和指针声明符,但相同功能的实现可以使用数组声明符:

 public class Deck {
    private Card[] cards; // cards是一个引用
    public Deck(int n) {
        this.cards = new Card[n];
    }
    public Card[] getCards() {
        return this.cards;
    }
}
int rows =;
int cols =;
Cell[][] array = new Cell[rows][cols]; 

函数或方法返回指针或引用:

 public class Main
{
    public static int[] reverse(int[] arr){
        int[] res = new int[arr.length];
        for(int i=,j=res.length-1;i<arr.length;i++,j--){
            res[j] = arr[i];
        }
        return res;
    }
    public static void main(String[] args) {
    int[] arr = {,2,3,4,5};
    int[] res = reverse(arr);
    for(int i=;i<res.length;i++)
    System.out.print(res[i]+" ");
    }
} 

14 字符串相关

静态引用的字串会自动转换成String 对象。和C 及C++不同,没有独立的静态字符数组字串可供使用。

C 和 C++ 没有内置的字符串类型,在 C 和 C++ 程序中使用 ” 终止符代表字符串的结束,在 Java 中字符串是用类对象 ( string 和stringBuffer )来实现的,这些类对象是 Java 语言的核心,用类对象实现字符串有以下几个优点:

  • 在整个系统中建立字符串和访问字符串元素的方法是一致的;
  • Java 字符串类是作为 Java 语言的一部分定义的,而不是作为外加的延伸部分;
  • Java 字符串执行运行时检查,可帮助排除一些运行时发生的错误;
  • 可对字符串用“+”进行连接操作。

C++ 字符串除了C风格字符格,一般都用 std::string ,对应 Java 的 String:

C++ string

Java(每个字符串都是对象)

std::string name(“Simon Zhang”);

String name = new String(“Simon Zhang”);

std::string name2 = “Simon Zhang”;

String name2 = “Simon Zhang”;

std::string surname = name.substr(6,5);

String surname = name .substring(6,11);

//第2个参数是子串长度,从位置6开始取5个字符

//第2个参数是end索引,取从位置6开始到位置11的子串

std::string newname = ” Jack” + surname;

String newname = “Jack” + surname;

newname.append(” is a good man!”);

newname.concat(” is a good man!”);

newname.length();

newname.length();

char k = newname.at(3);

char k = newname.charAt(3);

bool eq = (newname.compare(name) == 0);

boolean eq = newname.equals(name);

char k2 = newname[3];

char k2 = newname.charAt(3);

newname.clear();

newname = “”;

15 控制结构相关

15.1 goto 语句

“可怕”的 goto 语句是 C 和 C++ 的“遗物”,它是该语言技术上的合法部分,引用 goto 语句引起了程序结构的混乱,不易理解,goto 语句子要用于无条件转移子程序和多结构分支技术。鉴于以上理由,Java 不提供 goto 语句,它虽然指定 goto 作为关键字,但不支持它的使用,使程序简洁易读。

15.2 switch

java case标签支持字符串值。

15.3 break或continue+标签

break 和continue 关键字通常只中断当前循环,但若随同标签使用,它们就会中断到存在标签的地方。

 label:
外部循环{
    内部循环{
        //...
        break;      //
        //...
        continue;  //
        //...
        continue label; //3
        //...
        break label;    //4
    }
} 

16 输入输出

C++和Java的输入输出都是流的概念,但在语法上有细微区别:

 // C++
#include <vector>
#include <string>
#include <iostream>
int main()
{
    int no;
    std::string name;
    std::cin>>name>>no;
    std::cout<<"name is "<<name<<" no. is "<<no<<std::endl;
    std::cin.ignore();
    std::string str;
    std::getline(std::cin,str,'n');
    std::cout<<str<<std::endl;
}

// Java
import java.util.Scanner;
import java.io.*;
public class Main
{
    public static void main(String[] args) throws java.io.IOException{
        Scanner cin = new Scanner(System.in);
        String name = cin.next();
        int no = cin.nextInt();
        System.out.println("name is " + name + " no. is "+no);
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String str = in.readLine();
        System.out.println(str);
    }
} 

17 关键字与运算符相关

Java使用final代替const。

Java对每种数据类型都分配固定长度,如int类型总是32位的,无需sizeof运算符。

Java的布尔值(boolean)的能力非常有限。我们只能为其赋予true 和false 值。而且可测试它为真还是为假,但不可为它们再添加布尔值,或进行其他其他任何类型运算。

Java有三种移位运算符(C++只有下面的前两种):

左移位运算符(<<)能将运算符左边的运算对象向左移动运算符右侧指定的位数(在低位补0)。
“有符号”右移位运算符(>>)则将运算符左边的运算对象向右移动运算符右侧指定的位数。“有符号”右移位运算符使用了“符号扩展”:若值为正,则在高位插入0;若值为负,则在高位插入1。
Java 也添加了一种“无符号”右移位运算符(>>>),它使用了“零扩展”:无论正负,都在高位插入0。这一运算符是C 或C++没有的。

Java 允许方法重载(也就是C++中函数重载),但不允许运算符重载(用户层面)。Java可以使用运算符“+”来连接其它非字符串类型(也可以理解为语言内在层面的重载),在连接前将非字符串类型转换为字符串类型。

18 数据结构(容器)相关

对于面向对象编程言语,通常使用容器(容纳对象的对象)来表示数据结构。

Java内建了丰富的数据结构:列表,集合等等。

c++则用“模板库”同样提供了各种数据结构,但C++的容器之间并没有继承关系,其算法也并不使用容器引用做为参数(没有单根),也没有使用虚函数的动态绑定技术,而是引用一个中间层(迭代器)来实现算法对于容器的泛化(或通用性)。

 // C++
vector
list
deque
set
map
stack
queue

// Java
List(LinkedList, ArrayList)
Set(HashSe t,TreeSet)
Map(HashMap,HashTable,TreeMap) 

Java 没有模板或者参数化类型的其他形式。它提供了一系列集合:Vector(向量),Stack(堆栈)以及Hashtable(散列表),用于容纳Object 引用。利用这些集合,我们的一系列要求可得到满足。但这些集合并非是为实现象C++“标准模板库”(STL)那样的快速调用而设计的。

Java容器之间有继承关系且统一实现了Collections接口,该接口提供了各容器可以使用的公共方法,如

 java.util.Collections.sort(arraylist);
java.util.Collections.max(list);
java.util.Collections.shuffle(list);
Collections.binarySearch(list, 7);
Collections.copy(list, list2);
Collections.fill(list, "black");
Collections.frequency(collection, "red");

遍历:

 // C++
#include <vector>
#include <string>
#include <iostream>
int main()
{
    std::vector<std::string> strArr={"Tom","Jim","Jack","Henry"};
    for(std::string& str:strArr)
        std::cout<<str<<std::endl;
}

// java
import java.util.Collection;
public class Main
{
    public static void main(String[] args) {
        String[] str = {"Tom","Jim","Jack","Henry"};
        Collection<String> list=java.util.Arrays.asList(str);
        for(Object s:list)
            System.out.println(s);
    }
} 

容器用作函数或方法参数:

C++

java

container: iterator

collection self’s iterator as pararmeter

19 内存分区

C++并不是单纯的面向对象的编程语言,其融合了面向过程、面向对象、泛型等编程范式。其程序在运行前会先加载代码到代码区,加载全局数据和静态数据到全局区(主要是已初始化部分),针对字符串常量和其它const常量等数据加载到常量区。另外,在程序运行前会分配一定的栈区空间(供函数的局部非静态变量循环使用),在运行时可以动态申请堆空间。

Java使用了JVM,其一切皆类,一切皆对象,加载的是class代码。Java对堆的使用频率相对较高。因为JVM机制,其代码是独立于平台的,但也提供了依赖于平台的非Java代码的接口,称为本地(native)方法接口,对应的内存分区为本地方法栈。

20 使用场合

Java应用领域主要有两方面:

(1 ) web开发,也就是建设一些大型的网站;主要技术例如:J2EE、Spring、strus2、hibernate;操作数据库的JDBC;Java侧重于B/S模式,C偏向于C/S模式。

(2) android开发,特别是应用开发;就是现在流行的手机系统了;可以上网搜搜;资料很多;

而C++主要用于哪些比较大型的游戏或者对性能要求比较高的系统进行开发。

21 异常处理

Java 采取了不同的异常控制机制,因为此时已经不存在构建器。可添加一个finally 从句,强制执行特定的语句,以便进行必要的清除工作。Java 中的所有异常都是从基础类Throwable 里继承而来的,所以可确保我们得到的是一个通用接口。

 public void f(Obj b) throws IOException {
    myresource mr = b.createResource();
    try {
        mr.UseResource();
    } catch (MyException e) {
        // handle my exception
    } catch (Throwable e) {
        // handle all other exceptions
    } finally {
        mr.dispose(); // special cleanup
    }
} 

Java 的异常规范比C++的出色得多。丢弃一个错误的异常后,不是象C++那样在运行期间调用一个函数,Java 异常规范是在编译期间检查并执行的。除此以外,被取代的方法必须遵守那一方法的基础类版本的异常规范:它们可丢弃指定的异常或者从那些异常衍生出来的其他异常。这样一来,我们最终得到的是更为“健壮”的异常控制代码。

Almost all the methods in the I/O classes throw java.io.IOException. Therefore, you have to declare to throw java.io.IOException in the method in (a) or place the code in a try-catch block in (b), as shown below:

 // a
public static void main(String[] args)
throws IOException {
    // Perform I/O operations
}
// b
public static void main(String[] args) {
    try {
        // Perform I/O operations
    }
    catch (IOException ex) {
        ex.printStackTrace();
    }
} 

22 其它

数据作用域:

以下代码Java认为变量 i 是相同的作用域。

 public static void method() {
    int i =;
    int sum =;
    for(int i =; i < 10; i++) {
        sum += i;
    }
} 

C/C++是允许的,一对{}构成块作用域;认为for循环内的i是块作用域(for循环块)。

随机数函数略有区别:

 double d = Math.random(); // Java,值域是[,1), 0.0 =< Math.random < 1.0;
int a = rand(); // C++,值域是[,2^16),0<= rand() < RAND_MAX; 

Java内置了Java中的线程支持。Java中有一个thread类,inherit可以创建一个新的线程来重写run方法。C++没有内置的支持,它依赖于第三方库。

Java 提供对注释文档的内建支持,所以源码文件也可以包含它们自己的文档。通过一个单独的程序(通常是Javadoc文档),这些文档信息可以提取出来,并重新格式化成HTML。这无疑是文档管理及应用的极大进步。C++不支持文档注释。

Java有海量的中间件(C++主要是Boost),为了方便使用Java中间件,各IDE不断升级,开发一个简便使用的GUI界面插件。

Java通过包来组织类,C++通过头文件实现接口和模块化。

 // Java immutable class and object
public class Card {
    private final int rank;
    private final int suit;
    ...
} 

Java 通常显得更为健壮,为此采取的手段如下:

对象句柄初始化成null(一个关键字)
句柄肯定会得到检查,并在出错时丢弃异常
所有数组访问都会得到检查,及时发现边界违例情况
自动垃圾收集,防止出现内存漏洞
明确、“傻瓜式”的异常控制机制
为多线程提供了简单的语言支持
对网络程序片进行字节码校验

ref:

Bruce Eckel 《Thinking In Java》

Y. Daniel Liang 《Introduction to Java Programming and Data Structures》

-End-