java基础

来源:互联网 发布:6种网络拓扑结构图 编辑:程序博客网 时间:2024/06/07 17:46

【成员变量】

在类体内定义的变量,描述了类的静态属性,可以初始化,也可以不初始化,系统默认初始化为0。方法中定义的变量必须初始化。

【内存分配】

java中内存主要可分为四块:

1、 heap(堆)new出来的东西;

2、 stack(栈)局部变量;

3、 data segment静态变量及字符串常量;

4、 code segment存放代码。

【数组】

c/c+中的数组可以分配在栈上,而java中数据时引用类型,java中使用关键字new创建数组对象,格式为:int[] s; s = new int[5]; s在栈内存,而数组在堆内存,s存储了指向数组的应用。每个数组都有一个属性length指明它的长度。

【引用】

除基本类型之外的变量类型(基本类型为char int float double等)。Java中的对象是通过引用对其操作的。下面是对java/C++/C#中指针和引用的比较(转自网络):

1、变量、指针、引用的定义

int a = 1;int *c = &a;int &b = a;

c++ 引用语法,有一些是 Java/C# 程序员不知道的语法:

CMyClass &a1;

错误,C++ 引用变量定义的时候就要初始。Java/C# 对象变量,没有要求变量定义的时候,就要初始化。

CMyClass &a1 = NULL; 

错误,C++ 引用变量不能赋值null。

CMyClass &a1 = new CMyClass();

错误,C++ 引用变量不能赋值给一个 new 对象,这种情况,要用 C++ 指针。

以下C++ 代码是正确的:

CMyClass a;CMyClass &a1 = a;CMyClass *b =new CMyClass();CMyClass &b1 = *b; //这种写法不常用。

C++ 引用不能赋值 null, 不能赋值 new XXX();C++ 指针可以赋值 null, 可以赋值 new XXX()。C++ 引用对象通常在 stack 中,而C++ 指针 new出来的对象则在 heap 中。

Sun自称java中消灭了 C++ 中万恶的指针,自己的对象变量,都是引用。

 2、对象定义

C++的类对象变量定义语法较为复杂,可以定义在stack上(不用new),还可以定义在heap(用new)

CMyClass obj;      //stackCMyClass *p2 = new CMyClass()     //heap

java和c#没有这么复杂。在java/c#中,如下用法是错误的,会报空指针异常;但在c++中是合法的。

CMyClass obj;Obj.run();

在c++中,CMyClassobj;调用了构造函数,完成了变量初始化,而在java和c#中这相当于CMyClass obj = null;

java/C# 中的对象变量,可以赋值 null, 可以赋值 new XXX()。java/C# 中的对象变量在 heap 中。因此,java/C# 中的对象变量,更像是 C++ 中的指针,而不是 C++ 中的引用。

C++ 中,指针变量是一个 long 型整数,可以乱指的:

CMyClass *obj = (CMyClass *) 99; 

如果我知道一个内存地址,就可以定义一个C++指针变量,指向这个内存地址。C++ 的“引用”没有这个功能。C#/Java 的对象变量更没有这个功能。“指针乱指” 是 C++ 指针功能强大、灵活的体现(PC上最早出现播放视频的时候,大概是 intel 486 CPU 时代,C++软件通常都直接写显存,据说这样速度更快),也是最容易出问题的地方。估计是因为这个原因,所以C#/Java 都去掉了这个功能。所谓“万恶的C++指针”,多半,也是指的是“指针乱指”。

c++有野指针,即已经删除对象,但指针还是指向删除对象,还可以继续操作,但运行结果不保证正确。

CMyClass *p = new CMyClass();...//给 p 指向的内存赋值delete p;

这时 p 仍然指向之前的内存地址,该内存地址数据,一般情况下、短时间内,并没有被清空或者覆盖,仍然可以读/写。这就是“野指针”。

p->run(); //运行结果可能正确,可能不正确,没有保证。

此时指针 p 对应的内存,可能被下一个 new XXX() 代码,用了这个内存,因此,理论上讲,delete 之后的指针,不应再用来操作对象。

p= NULL; //将指针指向“空”,可以避免“野指针”问题。p->run(); //这里会报运行时错误。也就是空指针异常。空指针异常在 java/c# 中都有。

 3、变量回收问题

C++中,stack变量出了作用范围,内存自动回收;heap变量,需要手工delete。Java和c#中,变量是空闲时自动回收,不是变量出了作用范围就回收。如下面的c++代码:

{CMyClass obj;//stackobj.test();}

此处,stack变量自动被delete,内存自动回收

{CMyClass *p2 = new CMyClass();//heapp2->test();}

此处,超出变量p2的作用范围,下面不能再使用p2变量了,但是内存并未释放,有内存泄露。

4、delete和*

*和delete都是java和c#没有的,如下面的C++代码:

CMyClass *p1 = null;//c++必须带*CMyClass *p2 = new CMyClass();//c++必须带*p2->ab();delete p2;p2 = null;

java和c#不能带*,如下:

CMyClass p1 = null;CMyClass p2 = new CMyClass();

5、构造函数

C++有多种构造函数,如下:

CMyClass obj;              //调用构造函数CMyClass obj2 = obj;       //调用拷贝构造函数obj2 = obj;                //调用 = 操作符重载函数

java/C# 无操作符重载函数。而拷贝函数类似于java/c#中的clone函数,在java中,可以调用super.clone(),java基类Object默认有一个clone函数,而在c#中,clone函数并不会自动生成。


原创粉丝点击