java笔记
准备花时间把一些自己觉得值得注意的地方写下来分享一下。
一切都是对象
首先,java是一门基于c++的纯面向对象的语言,有一个非常重要的一点,就是,在java中,一切都被视为对象,包括后面的异常啊,甚至包括我们
的基本数据类型,他们公共的父类为Object。实例化后,我们操纵的标识符,并非直接操作其对象,而是对象的一个“引用”。我们最开始学习它
的特性,会经常因为这个概念理解的不够导致一些bug的发生。我在编程时一般会把它在一定程度上类比C的指针,但实际上并不是这样,java并不
是“按址传递”的,本质为“按值传递”。传递的是一个“对象的引用”。在后面数组赋值,类传递等,都是“引用”的传递。
int[] a={1,2,3}; int[] b; b=a;//注意,就是这里,并不是在内纯块上又建立了一个和a一样的数组,这里 b只是复制了a的一个引用,它表示的还是原来的内存块。 a[1]++; System.out.println(b[1]); ///~ OUTPUT 3
上面的例子一个是数组的部分,这里提前举出,再讲数组时会再深入。
存储方式
java在存储方式上与C有一定的区别,java中的对象存在堆中,属于一种通用的内存池。用new创建对象
String s=new String("hello");//字符串,与C++类似,C中用字符指针
C中存储方式为堆栈,,快速有效,但限制了程序的灵活性,java中对象不是存在这里,但某些数据还是用这种方式存储,如刚才讲的对象的引用。
当然Java的堆存储方式的灵活性也付出了应有的代价:存储分配和清理更加费时。
在c中,有一个经常用到的函数叫sizeof(),在内存分配时要用到。因为C的数据类型的大小是受机器硬件架构影响的。但在Java中是没有这个函
数的,因为Java是不需要这个函数的。这个已经被设计在语言里,各个基本类型所占大小都是不变的,具体大小可自行搜索查找,这个很容易的。
Java在内存上做了很多属于自己的优化:比如在C和C++中使用数组是很危险的一件事,大家都知道,数组在C中就是内存块,编译造成死循环的问
题我们已经见得很多了。并且Java有自己的“垃圾回收器”,有自己的内存回收机制,以后会单独讲一下Java内存回收的机理(这部分还是比较重
要的)。C,C++与Java中变量的存活周期,即作用域,是由花括号的位置来确定的,但有一个比较重要的区别:
{ int x = 12; { int x = 96; } }
上诉代码在C和C++是合法的,因为我们知道,在C里有全局变量局部变量等的定义,在小括号内对外面的x是有“隐藏”的效果。*但在java是不允许的。*
但是小括号消除的仅仅是引用,对象还将继续存在,即内存块还是在的。这里的回收就需要用到“垃圾回收器”。
初始化
类的成员变量定义时若未赋值,会给予它一个默认值,但这不包括“局部”变量,java中会编译错误,C++则只会给予警告。
static
静态全局变量有以下特点:
1.该变量在全局数据区分配内存;
2.静态全局变量在声明它的整个文件都是可见的,而在文件之外是不可见的;
3.静态变量都在全局数据区分配内存,包括后面将要提到的静态局部变量。
静态局部变量有以下特点:
1.该变量在全局数据区分配内存;
2.静态局部变量在程序执行到该对象的声明处时被首次初始化,即以后的函数调用不再进行初始化;
3.静态局部变量一般在声明处初始化,如果没有显式初始化,会被程序自动初始化为0;
4.它始终驻留在全局数据区,直到程序运行结束。但其作用域为局部作用域,当定义它的函数或语句块结束时,其作用域随之结束;
在函数的返回类型前加上static关键字,函数即被定义为静态函数。静态函数与普通函数不同,它只能在声明它的文件当中可见,不能被其它文件
使用。其它文件中可以定义相同名字的函数,不会发生冲突;
对于非静态数据成员,每个类对象都有自己的拷贝。而静态数据成员被当作是类的成员。无论这个类的对象被定义了多少个,静态数据成员在程序中
也只有一份拷贝,由该类型的所有对象共享访问。
关于静态成员函数,可以总结为以下几点:
1.出现在类体外的函数定义不能指定关键字static;
2.静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数;
3.非静态成员函数可以任意地访问静态成员函数和静态数据成员;
4.静态成员函数不能访问非静态成员函数和非静态数据成员;
5.由于没有this指针的额外开销,因此静态成员函数与类的全局函数相比速度上 会有少许的增长;
6.调用静态成员函数,可以用成员访问操作符(.)和(->;)为一个类的对象或指向类对象的指针调用静态成员函数,也可以直接使用如下格式:
<;类名>::<;静态成员函数名>;(<;参数表>;)
需要一个数据对象为整个类而非某个对象服务,同时又力求不破坏类的封装性,即要求此成员隐藏在类的内部,对外不可见时应使用static。
**下面简要总结静态变量与非静态的区别:
1.内存分配
静态变量在应用程序初始化时,就存在于内存当中,直到它所在的类的程序运行结束时才消亡;
而非静态变量需要被实例化后才会分配内存。
2.调用方式
静态变量只能通过“类.静态变量名”调用,类的实例不能调用;
非静态变量当该变量所在的类被实例化后,可通过实例化的类名直接访问。
3.共享方式
静态变量是全局变量,被所有类的实例对象共享,即一个实例的改变了静态变量的值,其他同类的实例读到的就是变化后的值;
非静态变量是局部变量,不共享的。
4.访问方式
静态成员不能访问非静态成员;
非静态成员可以访问静态成员。