Java Study.docx

上传人:b****8 文档编号:12976337 上传时间:2023-06-09 格式:DOCX 页数:29 大小:975.69KB
下载 相关 举报
Java Study.docx_第1页
第1页 / 共29页
Java Study.docx_第2页
第2页 / 共29页
Java Study.docx_第3页
第3页 / 共29页
Java Study.docx_第4页
第4页 / 共29页
Java Study.docx_第5页
第5页 / 共29页
Java Study.docx_第6页
第6页 / 共29页
Java Study.docx_第7页
第7页 / 共29页
Java Study.docx_第8页
第8页 / 共29页
Java Study.docx_第9页
第9页 / 共29页
Java Study.docx_第10页
第10页 / 共29页
Java Study.docx_第11页
第11页 / 共29页
Java Study.docx_第12页
第12页 / 共29页
Java Study.docx_第13页
第13页 / 共29页
Java Study.docx_第14页
第14页 / 共29页
Java Study.docx_第15页
第15页 / 共29页
Java Study.docx_第16页
第16页 / 共29页
Java Study.docx_第17页
第17页 / 共29页
Java Study.docx_第18页
第18页 / 共29页
Java Study.docx_第19页
第19页 / 共29页
Java Study.docx_第20页
第20页 / 共29页
亲,该文档总共29页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

Java Study.docx

《Java Study.docx》由会员分享,可在线阅读,更多相关《Java Study.docx(29页珍藏版)》请在冰点文库上搜索。

Java Study.docx

JavaStudy

1.基础部分

1.1Java版本

Java2SE--Java2PlatformStandEdition标准版,是桌面开发和低端商务应用的解决方案。

Java2EE--Java2PlatformEnterpriseEdition企业版,是以企业为为环境而开发应用程序结局方案。

Java2ME--Java2PlatformMicroEdition小型版,是致力于消费产品和嵌入式设备的最佳解决方案。

1.2Java编译过程

执行程序之前必须创建程序并进行编译,将Java源程序通过编译程序javac.exe编译为JVM—JavaVirtualMachine虚拟机可执行的代码,即java字节流。

JVM作用类似于windows操作系统,windows执行exe可执行文件的过程,就是从exe文件中取出一条条计算机指令,交给CPU去解释执行,同理JVM执行Java字节码文件的过程就是用字节码解释程序java.exe,也是JVM虚拟机从Java字节码文件中取出一条条字节码指令交给CPU去执行。

执行Java字节码的“CPU”可以是硬件,也可以是某个系统上运行的软件,这个软件就是Java虚拟机。

Java兼顾解释性与编译性的特点:

Java源文件转换成.class字节码文件的过程是编译型的,.class文件在操作系统上运行的过程则是解释型的,java虚拟机充当了解释器的作用。

环境变量配置:

path(C:

\ProgramFiles\Java\jdk1.6.0_10\bin);

CLASSPATH(.);

JAVA_HOME(C:

\ProgramFiles\Java\jdk1.6.0_10)

1.3变量基础

●intx=0,y;

y=x+2;

解析:

程序进行开始时,第一句代码分配了两块内存用于存储整数,分别用x、y作为这两块内存的变量名,x标记的内存中变量值是0,y标记的内存中变量值是未知数。

第二句代码执行时,先去取出x变量所在内存中的变量值,然后再进行加法运算,将结果放在y所在的内存单元中,作为y的变量值。

●不能使用如下运算:

byteb=5;

b=b-2;

解析:

在表达式求值时变量值会被自动提升为int值,表达式结果就会变成int型了,这时只要修改为:

b=(byte)(b-2)。

●intx=12;

{

intb=90;

System.out.println(“x=”+x);

System.out.println(“b=”+b);

}

b=x;

System.out.println(“nowb=”+b);

解析:

此段程序无法输出最后一句话对应的值,同时:

b=x;也会报错,说无法找到b变量,主要原因在于b变量作用域的越界了。

●{

intx=12;

{

intx=16;

x=x+4;//resultis20

}

x=x-2;//resultis10,butnot18

}

解析:

此段代码在C或C++中可以正常运行,原因在于C或C++两个x相当于两个变量,但是在java中却不允许如此。

●在java中允许形如:

x=y=z=8;的赋值方式,赋值以后,x、y、z都等于8。

对于有经验的程序员为避免出现”==”误写成”=”,就将形如:

”x==4”写成”4==x”,这样一旦误写就会报错容易排查。

1.4数组基础

在java中内存分为两种,一种是栈内存,一种是堆内存,在方法中定义的一些基本数据类型的变量和对象的引用变量都是在函数的栈内存中分配的,当在一段代码块即一对{}之间定义一个变量时,java就在栈里为这个变量分配内存空间,当超过变量作用域后,java会自动释放掉为该变量所分配的内存空间,该内存空间会立即被另作他用。

堆内存用来存放有new创建的对象和数组,在堆中分配的内存,由java虚拟机的自动垃圾回收器管理。

在堆中产生的一个数组或对象后,还可以在栈中定义一个特殊的变量,让栈中的这个变量取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成为了堆内存中的数组或对象的引用变量,这样就可以用栈中的引用变量去访问堆中的数组或对象,引用变量就相当于为数组或对象提供一个名称。

引用变量时普通变量,定义事在栈中分配,引用变量到期作用域之外被释放掉。

而数组和对象是在堆中分配的,即使运行到使用new产生的数组和对象语句所在代码块之外,数组和对象本身占据的内存本身不会释放掉,只有数组或对象没有引用变量指向它时,才会变成垃圾,不能再被使用,但仍然占据内存空间不放,在随后的不确定的时间里被垃圾回收器回收释放掉,由此可见java是比较占内存空间的。

●一维数组:

在java语言声明数组时,无论用何种方式定义数组,都不能指定其长度,形如intx[5];就是非法的,编译时会出错。

intx[]=newint[100];

解析:

等号左边的int[]相当于定义了一个特殊的变量符号x,x的数据类型是对int型数组对象的引用,x就是一个数组的引用变量,其引用的数组元素个数不定,就像定义一个基本数据类型变量,其初始值也是不确定的。

等号右边的newint[100]就是在堆内存中创建具有100个int变量的数组对象,而intx[]=newint[100];就是将右边的数组对象赋值给左边的数组引用变量。

可以按如方式理解:

int[]x;//定义了一个数组x,这条语句执行完后在内存中的情况如下图所示

x=newint[100];//数组初始化,这条语句执行完后在内存中的情况如下图所示:

 

执行第二句(x=newint[100])就在堆里面创建了一个数组对象,为这个数组对象分配了100个整数单元,并将数组对象赋值给了数组引用变量x。

●多维数组:

在java中没有真正意义上的多维数组,只有数组的数组。

在C语言中定义一个二维数组必须是一个x*y二维矩阵块,而java中的多位数组不一定是规则的矩阵块。

另外形如int[3][2]={{3,3},{3,4},{3,5}};都是非法的编译会出错。

intxx[][];

xx=newint[3][];

解析:

这两句代码表示数组xx有三个元素,每个元素都是int[]类型的一维数组,相当于定义了三个数组引用变量,分别为intxx[0][]、int[]xx[1]和int[]xx[2],我们可以把xx[0]理解为:

x、x、[、0、]这五个字母组合的变量名,即把形如x[1]想象成为一个变量名。

这里xx[0]、xx[1]和xx[2]都是数组引用变量,必须对它们赋值指向真正的数组对象,才能引用数组中的元素。

xx[0]=newint[3];

xx[1]=newint[2];

程序运行到这里时的内存分配情况如图:

 

1.5Java文档注释

文档注释提供将程序使用帮助信息嵌入到程序的功能,开发者可以使用javadoc工具将这些信息取出,然后转换成HTML的说明文档。

操作方法时在文本编写的java代码所在文件里的命令行里输入如下密令

javadoc–pclassname–version–authorclassname.java

2.类和对象

2.1对象的产生和使用

代码如下所示:

Personp1=newPerson();

解析:

类中要创建新的对象需要使用关键字new和要创建对象的类名,等号左边以类名Person作为变量类型定义了一个变量p1,来指向等号右边的new关键字创建的一个Person类实例对象,变量p1就是对象的引用变量,对象的引用变量时在栈中分配的内存,对象本身是在堆中分配的内存,此语句执行完之后在内存中的状态如图:

2.2访问局部变量和成员变量

代码如下所示:

classperson{

intage=99;//membervariable

voidsay(){

intage=89;//localvariable

System.out.println(age);

}

}

解析:

在这里say()方法的System.out.println(age);语句所访问的age就不是成员变量age而是局部变量age,即输出的值是89。

2.3对象的比较

代码如下所示:

classCompare{

publicstaticvoidmain(String[]args){

Stringstr1=newString("abcd");

Stringstr2=newString("abcd");

Stringstr3=st1;

System.out.println(str1==str2);//false

System.out.println(str1==str3);//true

System.out.println(str1.equals(str2));//true

System.out.println(str1.equals(str3));//true

System.out.println();

Stringst4="abcd";

Stringst5="abcd";

Stringst6=st4;

System.out.println(st4==st5);//true

System.out.println(st4==st6);//true

System.out.println(st4.equals(st5));//true

System.out.println(st4.equals(st6));//true

}

}

解析:

首先我们得理解在java中有两种比较对象是否相等的方式,一种是”==”运算符,一种是equals()方法,”==”是比较两个变量的值是否相等,equals()是比较两个对象的内容是否一致。

如果变量是指向一个数组或对象的引用变量时就如同上面的情况,str1,str2分别是在栈中定义的两个引用变量吗,存的是创建的两个对象内存地址,所以str1==str2的结果是false,而str1的内存地址赋值给str3,则str1==str3结果就是true;而第二种情况就是简单的赋值运算,则无论是用哪种比较方式,其结果都是true。

上述第一种情况如下图所示:

2.4类的封装性

所谓封装就是将类的成员变量声明为私有的(private),再提供一个或多个公有(public)方法实现对该成员变量的访问和修改。

封装可以达到如下目的:

1.隐藏类的实现细节。

2.让使用者只能通过事先定制好的方法访问数据,可以方便的加入控制逻辑,限制对属性的不合理操作。

3.便于修改,增强代码的可维护性。

4.可进行数据的检查。

我们在定义一个类的成员时需要对成员进行保护,要在定义一个成员(变量和方法)时使用private关键字说明成员的访问权限,这个成员成为了类的私有成员,只能被这个类的其他成员方法调用,而不能被其他类的方法调用。

如下代码所示:

classPerson{

privateintage=10;

publicvoidsay(){

System.out.println(age);//thereisnowrongincode

}

}

classTestPerson{

publicstaticvoidmain(String[]args){

newPerson().age=30;//thecodeiswrong,ageisprivatevariable,cannot//beaccessed

}

}

解析:

这段代码中age是Person类的私有变量,不能在其他类中直接修改和调用,一个类中的成员(变量和方法)一旦被private修饰就变成该类的私有成员,这个类之外的其他任何类就不能再访问它了。

如下代码所示:

classPerson{

privateintage=10;

publicstaticvoidmain(String[]args){

newPerson().say(newPerson());

}

publicvoidsay(Personperson){

System.out.println(person.age);//theresultis10

}

}

解析:

在这段代码中一共用newPerson()产生了两个对象,在第一个对象的say方法中成功的访问了第二个对象的private修饰的age变量,其输出结果是10。

2.5构造方法

构造方法可以为类的成员变量进行初始化工作,当一个类实例对象刚产生时,这个类的构造方法就会自动被调用,于是我们可以在这个构造方法中加入需要初始化的代码。

如果一个类中没有显示的定义任何构造方法,系统将自动的提供一个默认的无参构造方法,但是当这个类中定义了一个有参构造方法,没有人工定义一个无参构造方法,此时系统将不提供无参构造方法,当有调用该类的无参构造方法时将会报错。

如下代码所示:

Personp1=newPerson(“Tom”,18);

解析:

上述代码做了如下几件事1.创建了指定类的新实例对象;2.在堆内存中为新实例对象分配了内存空间,并调用了指定类的构造方法;3.将实例对象的首地址赋值给引用变量p1。

首先等号左边定义了一个Person类类型的引用变量p1,等号右边用new关键字创建了一个Person类的实例对象。

此时在内存中的状态如同所示:

然后调用相应的构造方法,构造方法接受外界传进来的姓名和年龄,在执行构造方法中的代码之前,要进行属性的显示初始化,即执行在定义成员变量时就对其进行初始化赋值的语句,也即Person类中的代码:

privateStringname=“unknown”;

privateintage=-1;

此时内存状态如图所示:

接着执行构造方法中的代码,用从外部接受的姓名和年龄对成员变量重新赋值,此时内存状态如图所示:

最后把刚刚创建的对象赋给引用变量p1,此时内存状态如图所示:

2.6this关键字

如下代码所示:

classA{

Stringname;

publicA(Stringx){

name=x;

}

publicvoidfunc1(){

System.out.println(”func1”of+name+”iscalling”);

}

publicvoidfunc2(){

Aa2=newA(”a2”);

a2.func1();

}

}

classTestA{

publicstaticvoidmain(String[]args){

Aa1=newA(”a1”);

a1.func2();

}

}

解析:

在上面的代码程序中一共产生了两个类A的实例对象,在a1的func2中调用了a2的func1。

在func2方法中代码被调用时在内存中的状态如图所示:

两个需要理解的地方:

func2被调用说明一定是事先已经有了一个存在的对象,这样func2就被作为那个对象的方法被调用;func2内部能够引用别的对象,func2也能够引用那个“事先存在并对func2进行调用”的对象,即func2所属那个对象。

于是此时this关键字就起到了说明func2所属对象的作用,

代码修改如下:

classA{

Stringname;

publicA(Stringx){

name=x;

}

publicvoidfunc1(){

System.out.println(”func1”of+name+”iscalling”);

}

publicvoidfunc2(){

Aa2=newA(”a2”);

this.func1();//usethekeywordsthistocallfunctionfunc1

a2.func1();

}

}

classTestA{

publicstaticvoidmain(String[]args){

Aa1=newA(”a1”);

a1.func2();

}

}

每个成员方法内部都有一个this引用变量指向调用这个方法的对象,上述代码中所有的类A中的成员方法与this之间的关系如图所示:

2.7Java垃圾回收

在java中有一个方法时finalize(),是从Object那继承来的方法,也即任何一个类都会从Object那继承这个方法。

这里理解finalize()方法很重要,这里可以跟C++中的析构方法对比理解,只要某个对象的构造方法被调用了,知道一个对象刚产生了,那么只要某个对象的析构方法被调用了,我们就知道这个对象即将会消亡。

由于类代码的编写早于对象的产生,利用构造和析构方法我们就可以提前对对象的产生和消亡过程进行一些控制。

“皮之不存毛将安附焉”,所以无论是构造方法被调用还是析构方法被调用,对象都在内存中存在着。

然而finalize()方法的作用就不如C++中的析构方法那么重要了,它是在对象被当成垃圾从内存释放前被调用,而不是在对象变成垃圾前被调用。

并且垃圾回收器的启用不由程序员控制,也无规律可循,并不会一产生垃圾,它就会被唤起,有时候甚者到程序终止它都没有被调用。

如下代码所示:

classgh{

publicvoidfinalize(){

System.out.println("thismethodhasbeencalled");

}

publicstaticvoidmain(String[]args){

newgh();

newgh();

//System.gc();

System.out.println("thisisthecodeend");

}

}

编译运行结果是:

thisisthecodeend

在上述代码中在执行

System.out.println("thisisthecodeend");语句前所产生的两个匿名对象都变成了垃圾但我们并没有看到垃圾回收时finalize()方法被调用的效果。

可见到程序结束都没有调用finalize()方法。

但是当我们去除System.gc()方法的注释时,我们发现程序运行结果是:

thisisthecodeend

thismethodhasbeencalled

thismethodhasbeencalled

Java里提供了这个System.gc()的方法,使用这个方法可以强制启动垃圾回收器来回收垃圾。

2.8方法的参数传递

方法的参数传递这里可以区分为基本数据类型参数传递和引用数据类型参数传递。

●基本类型的变量当做实参传递并不能改变这个变量的值,考虑如下代码:

classChange{

publicstaticvoidmain(String[]args){

intx=5;

chang(x);

System.out.println(x);

}

publicstaticvoidchange(intx){

x=3;

}

}

运行输出结果是:

5

解析:

方法的形式参数就相当于方法中定义的局部变量,方法调用结束时也就释放掉了,不会影响到主程序中同名的局部变量,这样就可以理解为什么上述代码输出结果是5而不是3了,原因就在于它们在内存中是不同的两个区域名称相同的变量。

如下图解:

●引用数据类型参数传递中对象的引用变量并不是对象本身,它们只是对象的句柄,换句话说就是对象的一个名字,一个对象可以有好几种称呼,如同一个人有好几种叫法,比如熊是一个人,但是绰号B哥也是这个人,说B哥好色也就是说熊好色。

考虑如下代码:

publicclassChange{

intx;

publicstaticvoidmain(String[]args){

Changech=newChange();

ch.x=5;

change(ch);

System.out.println(ch.x);

}

publicstaticvoidchange(Changech){

ch.x=3;

}

}

编译运行上述代码,输出结果是:

3

解析:

这里main方法中的change值没有改变,所以还是指向那个对象,但是指向对象的内容已经在change方法中被改变,所以可以这样理解change方法中的ch就如同main方法中的ch的别名,对change方法中的ch进行操作也就是对main方法中的ch进行操作,其结果自然会改变。

2.9static关键字

采用static关键字说明类的属性和方法不属于类的某个实例对象,

●在类的变量名前加上static关键字,我们称这种变量为静态成员变量。

如下代码所示:

publicclassChinese{

staticStringcountry=”中国”;

Stringname;

intage;

voidsay(){

System.out.println(”mycountryis”+country);

}

}

classtestChinese{

publicstaticvoidmain(String[]args){

System.out.println(”B’scountryis”+Chinese.country);

Chinsesech=newChiense();

System.out.println(”C’scountryis”+ch.country);

}

}

解析:

读上述代码我们发现可以发现类中成员方法可以直接访问静态成员变量,也可以直接使用”类名.成员”格式去访问静态成员变量,还可以使用”对象名.成员”的格式去访问静态成员变量。

静态成员变量在某种程度上去其他语言的全局变量相类似,如果不是私有的话就可以在类的外部进行访问,此时就不用产生类的实例对象,直接用”类名.成员”的格式访问静态成员变量。

●在类中定义的方法前加上static关键字,称这种方法为静态成员方法。

同静态成员变量一样,可以用类名直接访问静态成员方法,可以用类的实例对象访问静态成员方法,可以在类的非静态成员方法中像访问其他非静态方法一样访问此静态成员方法。

如下代码段:

publicclassChinese{

staticvoidsay(){

System.out.println(”mycountryis”);

}

voidsing(){

say();

}

}

classtestChinese{

publicstaticvoidmain(String[]args){

System.out.println(”B’scountryis”+Chinese.say());

Chinsesech=newChiense();

System.out.println(”C’scountryis”+ch.say());

}

}

●使用静态方法注意几点

1.在静态方法中只能直接调用同类中其他的静态成员(属性和方法),而不能直接访问类中非静态成员。

这是因为对于非静态成员(属性和方法)需要创建类的实例对象后才可以使用,而静态方法在使

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 总结汇报 > 学习总结

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2