java基础知识(耐心看,好不容易才整理的,虽然很乱).docx_第1页
java基础知识(耐心看,好不容易才整理的,虽然很乱).docx_第2页
java基础知识(耐心看,好不容易才整理的,虽然很乱).docx_第3页
java基础知识(耐心看,好不容易才整理的,虽然很乱).docx_第4页
java基础知识(耐心看,好不容易才整理的,虽然很乱).docx_第5页
已阅读5页,还剩36页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

分类: 1 什么是对象?什么是类?什么是包?什么是接口?什么是内部类?2 面向对象编程的特性有哪三个?它们各自又有哪些特性?3 你知道java语言在面向对象编程方面有何独特的特点吗?难点:1 理解方法重载和方法重写,不要混淆了两者的使用。2 类变量和类方法的使用。3 接口的使用。31 面向对象技术基础311 面向对象的基本概念面向对象的基本思想面向对象是一种新兴的程序设计方法,或者是一种新的程序设计规范(paradigm),其基本思想是使用对象、类、继承、封装、消息等基本概念来进行程序设计。从现实世界中客观存在的事物(即对象)出发来构造软件系统,并且在系统构造中尽可能运用人类的自然思维方式。开发一个软件是为了解决某些问题,这些问题所涉及的业务范围称作该软件的问题域。其应用领域不仅仅是软件,还有计算机体系结构和人工智能等。1 对象的基本概念对象是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位。一个对象由一组属性和对这组属性进行操作的一组服务组成。主动对象是一组属性和一组服务的封装体,其中至少有一个服务不需要接收消息就能主动执行(称作主动服务)。2 类的基本概念类是具有相同属性和服务的一组对象的集合,它为属于该类的所有对象提供了统一的抽象描述,其内部包括属性和服务两个主要部分。在面向对象的编程语言中,类是一个独立的程序单位,它应该有一个类名并包括属性说明和服务说明两个主要部分。3 消息消息就是向对象发出的服务请求,它应该包含下述信息:提供服务的对象标识、服务标识、输入信息和回答信息。服务通常被称为方法或函数。312 面向对象的基本特征1封装性封装性就是把对象的属性和服务结合成一个独立的相同单位,并尽可能隐蔽对象的内部细节,包含两个含义: 把对象的全部属性和全部服务结合在一起,形成一个不可分割的独立单位(即对象)。 信息隐蔽,即尽可能隐蔽对象的内部细节,对外形成一个边界或者说形成一道屏障,只保留有限的对外接口使之与外部发生联系。封装的原则在软件上的反映是:要求使对象以外的部分不能随意存取对象的内部数据(属性),从而有效的避免了外部错误对它的交叉感染,使软件错误能够局部化,大大减少查错和排错的难度。2继承性特殊类的对象拥有其一般类的全部属性与服务,称作特殊类对一般类的继承。一个类可以是多个一般类的特殊类,它从多个一般类中继承了属性与服务,这称为多继承。 在java语言中,通常我们称一般类为父类(superclass,超类),特殊类为子类(subclass)。3多态性对象的多态性是指在一般类中定义的属性或服务被特殊类继承之后,可以具有不同的数据类型或表现出不同的行为。这使得同一个属性或服务在一般类及其各个特殊类中具有不同的语义。例如:几何图形的绘图方法,椭圆和多边形都是几何图的子类,其绘图方法功能不同。313 面向对象程序设计方法OOAObject Oriented Analysis 面向对象的分析OODObject Oriented Design 面向对象的设计OOIObject Oriented Implementation 面向对象的实现32 Java语言的面向对象特性321 类类是java中的一种重要的复合数据类型,是组成java程序的基本要素。它封装了一类对象的状态和方法,是这一类对象的原形。一个类的实现包括两个部分:类声明和类体1类声明:publicabstract|final class className extends superclassName implements interfaceNameList其中,修饰符public,abstract,final 说明了类的属性,className为类名,superclassName为类的父类的名字,interfaceNameList为类所实现的接口列表。2类体类体定义如下:class classNamepublic | protected | private static final transient volatile typevariableName;/成员变量public | protected | private staticfinal | abstract native synchronizedreturnType methodName(paramList) throws exceptionListstatements /成员方法3成员变量成员变量的声明方式如下:public | protected | private static final transient volatile typevariableName; /成员变量其中,static: 静态变量(类变量);相对于实例变量final: 常量transient: 暂时性变量,用于对象存档,用于对象的串行化,见对象的串行化一节volatile: 贡献变量,用于并发线程的共享4成员方法方法的实现包括两部分内容:方法声明和方法体。public | protected | private staticfinal| abstract native synchronizedreturnType methodName(paramList)throws exceptionList /方法声明statements /方法体方法声明中的限定词的含义:static: 类方法,可通过类名直接调用abstract: 抽象方法,没有方法体final: 方法不能被重写native: 集成其它语言的代码synchronized: 控制多个并发线程的访问 方法声明方法声明包括方法名、返回类型和外部参数。其中参数的类型可以是简单数据类型,也可以是复合数据类型(又称引用数据类型)。对于简单数据类型来说,java实现的是值传递,方法接收参数的值,但不能改变这些参数的值。如果要改变参数的值,则用引用数据类型,因为引用数据类型传递给方法的是数据在内存中的地址,方法中对数据的操作可以改变数据的值。例3-1说明了简单数据类型与引用数据的区别。【例3-1】import java.io.*;public class PassTestfloat ptValue;public static void main(String args) int val;PassTest pt=new PassTest();val=11;System.out.println(Original Int Value is:+val); pt.changeInt(val); /值参数System.out.println(Int Value after Change is: +val); /*值参数 值的修改,没有影响值参数的值*/pt.ptValue=101f;System.out.println(Original ptValue is:+pt.ptValue);pt.changeObjValue(pt); /引用类型的参数System.out.println(ptValue after Change is:+pt.ptValue);/* 引用参数值的修改,改变了引用参数的值*/ public void changeInt(int value)value=55; /在方法内部对值参数进行了修改public void changeObjValue(PassTest ref)ref.ptValue=99f; /在方法内部对引用参数进行了修改 方法体方法体是对方法的实现,它包括局部变量的声明以及所有合法的Java指令。方法体中声明的局部变量的作用域在该方法内部。若局部变量与类的成员变量同名,则类的成员变量被隐藏。为了区别参数和类的成员变量,我们必须使用this。this-用在一个方法中引用当前对象,它的值是调用该方法的对象。返回值须与返回类型一致,或者完全相同,或是其子类。当返回类型是接口时,返回值必须实现该接口。5方法重载方法重载是指多个方法享有相同的名字,但是这些方法的参数必须不同,或者是参数的个数不同,或者是参数类型不同。返回类型不能用来区分重载的方法。参数类型的区分度一定要足够,例如不能是同一简单类型的参数,如int与long。编译器会根据参数的个数和类型来决定当前所使用的方法。6 构造方法 构造方法是一个特殊的方法。Java 中的每个类都有构造方法,用来初始化该类的一个对象。 构造方法具有和类名相同的名称,而且不返回任何数据类型。 重载经常用于构造方法。 构造方法只能由new运算符调用322 对象类实例化可生成对象,对象通过消息传递来进行交互。消息传递即激活指定的某个对象的方法以改变其状态或让它产生一定的行为。一个对象的生命周期包括三个阶段:生成、使用和消除。对象的清除当不存在对一个对象的引用时,该对象成为一个无用对象。Java的垃圾收集器自动扫描对象的动态内存区,把没有引用的对象作为垃圾收集起来并释放。System.gc( );System.exit();/terminate the current JVM当系统内存用尽或调用System.gc( )要求垃圾回收时,垃圾回收线程与系统同步运行。323 面向对象特性java语言中有三个典型的面向对象的特性:封装性、继承性和多态性。1 封装性java语言中,对象就是对一组变量和相关方法的封装,其中变量表明了对象的状态,方法表明了对象具有的行为。通过对象的封装,实现了模块化和信息隐藏。通过对类的成员施以一定的访问权限,实现了类中成员的信息隐藏。 java类中的限定词java语言中有四种不同的限定词,提供了四种不同的访问权限。1) private 类中限定为private的成员,只能被这个类本身访问。如果一个类的构造方法声明为private,则其它类不能生成该类的一个实例。2) default类中不加任何访问权限限定的成员属于缺省的(default)访问状态:friend,可以被这个类本身和同一个包中的类所访问。3) protected类中限定为protected的成员,可以被这个类本身、它的子类(包括同一个包中以及不同包中的子类)和同一个包中的所有其他的类访问。4) public类中限定为public的成员,可以被所有的类访问。【表3-1】java中类的限定词的作用范围比较同一个类同一个包 不同包的子类 不同包非子类private*default *protected*public*2 继承性通过继承实现代码复用。Java中所有的类都是通过直接或间接地继承java.lang.Object类得到的。继承而得到的类称为子类,被继承的类称为父类。子类不能继承父类中访问权限为private的成员变量和方法。子类可以重写父类的方法,及命名与父类同名的成员变量。但Java不支持多重继承,即一个类从多个超类派生的能力。 成员变量的隐藏和方法的重写子类通过隐藏父类的成员变量和重写父类的方法,可以把父类的状态和行为改变为自身的状态和行为。例如:class SuperClassint x; void setX( ) x=0; class SubClass extends SuperClassint x; /隐藏了父类的变量xvoid setX( ) /重写了父类的方法 setX()x=5; .注意:子类中重写的方法和父类中被重写的方法要具有相同的名字,相同的参数表和相同的返回类型,只是函数体不同。 superjava中通过super来实现对父类成员的访问,super用来引用当前对象的父类。Super 的使用有三种情况:1)访问父类被隐藏的成员变量,如:super.variable; 2)调用父类中被重写的方法,如:super.Method(paramlist);3)调用父类的构造函数,如:super(paramlist);【例3-5】import java.io.*;class SuperClassint x;SuperClass( ) x=3;System.out.println(in SuperClass : x= +x);void doSomething( ) System.out.println(in SuperClass.doSomething();class SubClass extends SuperClass int x;SubClass( ) super( ); /调用父类的构造方法x=5;/super( ) 要放在方法中的第一句System.out.println(in SubClass :x=+x);void doSomething( ) super.doSomething( ); /调用父类的方法System.out.println(in SubClass.doSomething();System.out.println(super.x=+super.x+ sub.x=+x);public class Inheritance public static void main(String args) SubClass subC=new SubClass();subC.doSomething();3 多态性在java语言中,多态性体现在两个方面:由方法重载实现的静态多态性(编译时多态)和方法重写实现的动态多态性(运行时多态)。1) 编译时多态在编译阶段,具体调用哪个被重载的方法,编译器会根据参数的不同来静态确定调用相应的方法。2) 运行时多态由于子类继承了父类所有的属性(私有的除外),所以子类对象可以作为父类对象使用。程序中凡是使用父类对象的地方,都可以用子类对象来代替。一个对象可以通过引用子类的实例来调用子类的方法。 重写方法的调用原则:java运行时系统根据调用该方法的实例,来决定调用哪个方法。对子类的一个实例,如果子类重写了父类的方法,则运行时系统调用子类的方法;如果子类继承了父类的方法(未重写),则运行时系统调用父类的方法。在例3-6中,父类对象a引用的是子类的实例,所以,java运行时调用子类B的callme方法。【例3-6】import java.io.*;class Avoid callme( ) System.out.println(Inside As callme()method); class B extends Avoid callme( ) System.out.println(Inside Bs callme() Method); public class Dispatchpublic static void main(String args) A a=new B();a.callme( ); 方法重写时应遵循的原则:1)改写后的方法不能比被重写的方法有更严格的访问权限(可以相同)。2)改写后的方法不能比重写的方法产生更多的例外。4 其它 final 关键字final 关键字可以修饰类、类的成员变量和成员方法,但final 的作用不同。1) final 修饰成员变量:final修饰变量,则成为常量,例如final type variableName;修饰成员变量时,定义时同时给出初始值,且以后不能被修改,而修饰局部变量时不做要求。2) final 修饰成员方法:final修饰方法,则该方法不能被子类重写final returnType methodName(paramList)3) final 类: final修饰类,则类不能被继承final class finalClassName 实例成员和类成员用static 关键字可以声明类变量和类方法,其格式如下:static type classVar;static returnType classMethod(paramlist) 如果在声明时不用static 关键字修饰,则声明为实例变量和实例方法。1) 实例变量和类变量每个对象的实例变量都分配内存,通过该对象来访问这些实例变量,不同的实例变量是不同的。类变量仅在生成第一个对象时分配内存,所有实例对象共享同一个类变量,每个实例对象对类变量的改变都会影响到其它的实例对象。类变量可通过类名直接访问,无需先生成一个实例对象,也可以通过实例对象访问类变量。2) 实例方法和类方法实例方法可以对当前对象的实例变量进行操作,也可以对类变量进行操作,实例方法由实例对象调用。但类方法不能访问实例变量,只能访问类变量。类方法可以由类名直接调用,也可由实例对象进行调用。类方法中不能使用this或super关键字。例3-7 是关于实例成员和类成员的例子。【例3-7】class Member static int classVar;int instanceVar;static void setClassVar(int i) classVar=i;/ instanceVar=i; / 类方法不能访问实例变量static int getClassVar() return classVar; void setInstanceVar(int i) classVar=i; /实例方法不但可以访问类变量,也可以实例变量instanceVar=i; int getInstanceVar( ) return instanceVar; public class MemberTestpublic static void main(String args) Member m1=new member(); Member m2=new member(); m1.setClassVar(1); m2.setClassVar(2); System.out.println(m1.classVar=+m1.getClassVar()+ m2.ClassVar=+m2.getClassVar(); m1.setInstanceVar(11); m2.setInstanceVar(22); System.out.println(m1.InstanceVar=+m1.getInstanceVar()+ m2.InstanceVar=+m2.getInstanceVar(); 类java.lang.Object类java.lang.Object处于java开发环境的类层次的根部,其它所有的类都是直接或间接地继承了此类。该类定义了一些最基本的状态和行为。下面,我们介绍一些常用的方法。equals() :比较两个对象(引用)是否相同。getClass():返回对象运行时所对应的类的表示,从而可得到相应的信息。toString():用来返回对象的字符串表示。finalize():用于在垃圾收集前清除对象。notify(),notifyAll(),wait():用于多线程处理中的同步。324抽象类和接口1 抽象类java语言中,用abstract 关键字来修饰一个类时,这个类叫做抽象类,用abstract 关键字来修饰一个方法时,这个方法叫做抽象方法。格式如下:abstract class abstractClass /抽象类abstract returnType abstractMethod(paramlist) /抽象方法抽象类必须被继承,抽象方法必须被重写。抽象方法只需声明,无需实现;抽象类不能被实例化,抽象类不一定要包含抽象方法。若类中包含了抽象方法,则该类必须被定义为抽象类。若一个类继承了一个抽象类,则抽象类的抽象方法必须被实现,否则子类必须声明为abstract.2 接口接口是抽象类的一种,只包含常量和方法的定义,而没有变量和方法的实现,且其方法都是抽象方法。它的用处体现在下面几个方面: 通过接口实现不相关类的相同行为,而无需考虑这些类之间的关系。 通过接口指明多个类需要实现的方法。 通过接口了解对象的交互界面,而无需了解对象所对应的类。1)接口的定义接口的定义包括接口声明和接口体。接口声明的格式如下:public interface interfaceNameextends listOfSuperInterface extends 子句与类声明的extends子句基本相同,不同的是一个接口可有多个父接口,用逗号隔开,而一个类只能有一个父类。接口体包括常量定义和方法定义常量定义格式为:type NAME=value; 该常量被实现该接口的多个类共享; 具有public ,final, static的属性。在接口中只能声明常量,不可以声明变量。方法体定义格式为:(具有 public和abstract属性,不能声明为protected)returnType methodName(paramlist);注意:在接口的实现类中,实现的接口方法必须声明为public ,因为接口中定义的方法为public(默认)。所以其实现必须声明为public.否则编译不会通过。2)接口的实现在类的声明中用implements子句来表示一个类使用某个接口,在类体中可以使用接口中定义的常量,而且必须实现接口中定义的所有方法。一个类可以实现多个接口,在implements子句中用逗号分开。3) 接口类型的使用接口作为一种引用类型来使用。任何实现该接口的类的实例都可以存储在该接口类型的变量中,通过这些变量可以访问类所实现的接口中的方法。325 内部类1 内部类的定义和使用:内部类是在一个类的内部嵌套定义的类,它可以是其它类的成员,也可以在一个语句块的内部定义,还可以在表达式内部匿名定义。内部类有如下特性: 一般用在定义它的类或语句块之内,在外部引用它时必须给出完整的名称.名字不能与包含它的类名相同。 可以使用包含它的类的静态和实例成员变量,也可以使用它所在方法的局部变量。 可以定义为abstract。 可以声明为private或protected。 若被声明为static,就变成了顶层类,不能再使用局部变量。 若想在Inner Class中声明任何static成员,则该Inner Class必须声明为static。例3-8】import java.awt.*;import java.awt.event.*;public class TwoListenInner private Frame f;private TextField tf;public static void main(String args) TwoListenInner that=new TwoListenInner();that.go(); public void go() f=new Frame(Two listeners example);f.add(North,new Label(Click and drag the mouse);tf=new TextField(30);f.add(South,tf);f.addMouseMotionListener(new MouseMotionHandler();f.addMouseListener(new MouseEventHandler();f.setSize(300,300);f.setVisible(true); public class MouseMotionHandler extends MouseMotionAdapter public void mouseDragged(MouseEvent e)String s=Mouse dragging:X=+e.getX()+Y=+e.getY();tf.setText(s);public class MouseEventHandler extends MouseAdapter public void mouseEntered(MouseEvent e)String s=The mouse entered;tf.setText(s);public void mouseExited(MouseEvent e)String s=The mouse left the building;tf.setText(s);说明:Frame类的add方法来自于其祖先类Container类,addMouseMotionListener和addMouseListener方法来自于其祖先类Component, addMouseListener方法的参数为MouseListener接口,MouseAdapter类是实现了MouseListener接口的类。可见图形界面对于外部事件的响应是通过添加listener实现的2 匿名类的定义和使用:匿名类是一种特殊的内部类,它是在一个表达式内部包含一个完整的类定义。通过对例6-7中go()部分语句的修改,我们可以看到匿名类的使用情况。public void go() f=new Frame(Two listeners example);f.add(North,new Label(Click and drag the mouse);tf=new TextField(30);f.add(South,tf);f.addMouseMotionListener(new MouseMotionHandler()/*定义了一个匿名类,类名没有显式地给出,只是该类是MouseMotionHandler类的子类*/public void mouseDragged(MouseEvent e)String s=Mouse dragging:X=+e.getX()+Y=+e.getY();tf.setText(s););f.addMouseListener(new MouseEventHandler();f.setSize(300,300);f.setVisible(true);3 内部类的优缺点: 优点:节省编译后产生的字节码文件的大小 缺点:使程序结构不清楚附录类、方法、成员变量和局部变量的可用修饰符修饰符类成员方法构造方法成员变量局部变量abstractYY_static_Y_Y_publicYYYY_protected_YYY_private_YYY_synchronized_Y_native_Y_transient_Y_volatile_Y_finalYY_YY1、访问控制修饰符:Java语言采用访问控制修饰符来控制类及类的方法和变量的访问权限,从而只向使用者暴露接口,但隐藏实现细节。 公开级别:用public修饰,对外公开 受保护级别:用protected修饰,向子类及同一个包中的类公开 默认级别:没有访问控制修饰符,向同一个包中的类公开 私有级别:用private修饰,只有 类本身可以访问,不对外公开顶层类只有默认或公开级别,因此不能用private和protected来修饰。2、abstract修饰符:用来修饰类和成员方法,抽象类不能被实例化,抽象方法不提供具体的实现。 抽象类中可以没有抽象方法,但包含了抽象方法的类必须被定义为抽象类 如果子类没有实现父类中所有的抽象方法,那么子类也必须被定义为抽象类 没有抽象构造方法,也没有抽象静态方法 抽象类中可以有非抽象的构造方法,创建子类的实例时可能会调用这些构造方法 抽象类及抽象方法不能被final修饰符修饰(原因?)3、final修饰符: 具有“不可更改的”意义,它可以修饰非抽象类飞、非抽象成员方法和变量。 用final修饰的类不能被继承,没有子类 用final修饰的方法不能被子类的方法覆盖 用final修饰的变量表示常量,只能被赋一次值 final不能用来修饰构造方法,无意义(为什么?)final类: 不是专门继承而设计的类 出于安全的原因,类的实现细节不允许有任何改动 在创建对象模型时,确信这个类不会再被扩展final方法: 出于安全的原因,父类不允许子类覆盖某个方法,此时可以把这个方法声明为finalfinal变量特征: 可以修饰静态变量,实例变量和局部变量,分别表示静态常量,实例常量和局部常量 final变量都必须显示初始化 final变量只能赋一次值 如果将引用类型的变量用final修饰,那么该变量只能始终只能引用一个对象,但可以改变内容final定义常量,有如下作用: 提高程序的安全性,禁止非法修改取值固定且不允许改变的数据 提高程序代码的可维护性 提高程序代码的可读性4、static修饰符: 用static修饰的变量表示静态变量,可以直接通过类名来访问。 用static修饰的成员方法表示静态方法,可以直接通过类名来访问。 用static修饰的程序代码块表示静态代码块,当Java虚拟机加载类时,就会执行该快代码static变量: 静态变量在内存中只有一个拷贝 对于实例变量每创建一个实例,就分配一次内存;而且互不影响 静态变量能被类的所有实例共享,可作为实例之间进行交流的共享数据static方法(why)静态方法中不能用this关键字,也不能直接访问所属类的实例变量和实例方法 可以直接访问所属类的静态变量和静态方法 静态方法中也不能用super关键字 一个静态的方法不能被定义为抽象方法,必须实现static代码块 类中也可以包含静态代码块,它不存在于任何方法体中。 Java虚拟机加载类时会执行这些静态代码块。类的构造方法用于初始化类的实例,而类的静态代码块则可用于初始化类。 静态代码块与静态方法一样,也不能直接访问类的实例变量和实例方法,而必须通过实例的引用来访问1.java是如何管理内存的java的内存管理就是对象的分配和释放问题。(其中包括两部分)分配:内存的分配是由程序完成的,程序员需要通过关键字new为每个对象申请内存空间(基本类型除外),所有的对象都在堆(Heap)中分配空间。释放:对象的释放是由垃圾回收机制决定和执行的,这样做确实简化了程序员的工作。但同时,它也加重了JVM的工作。因为,GC为了能够正确释放对象,GC必须监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等,GC都需要进行监控。2.什么叫java的内存泄露在java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点,首先,这些对象是可达的,即在有向图中,存在通路可以与其相连(也就是说仍存在该内存对象的引用);其次,这些对象是无用的,即程序以后不会再使用这些对象。如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存。3.JVM的内存区域组成java把内存分两种:一种是栈内存,另一种是堆内存(1)在函数中定义的基本类型变量和对象的引用变量都在函数的栈内存中分配;(2)堆内存用来存放由new创建的对象和数组以及对象的实例变量。在函数(代码块)中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量所分配的内存空间;在堆中分配的内存由java虚拟机的自动垃圾回收器来管理堆和栈的优缺点堆的优势是可以动态分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的。缺点就是要在运行时动态分配内存,存取速度较慢;栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。另外,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。4.java中数据在内存中是如何存储的a)基本数据类型java的基本数据类型共有8种,即int,short,long,byte,float,double,boolean,char(注意,并没有String的基本类型)。这种类型的定义是通过诸如int a = 3;long b = 255L;的形式来定义的。如int a = 3;这里的a是一个指向int类型的引用,指向3这个字面值。这些字面值的数据,由于大小可知,生存期可知(这些字面值定义在某个程序块里面,程序块退出后,字段值就消失了),出于追求速度的原因,就存在于栈中。另外,栈有一个很重要的特殊性,就是存在栈中的数据可以共享。比如:我们同时定义:int a=3;int b=3;编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找有没有字面值为3的地址,没找到,就开辟一个存放3这个字面值的地址,然后将a指向3的地址。接着处理int b = 3;在创建完b这个引用变量后,由于在栈中已经有3这个字面值,便将b直接指向3的地址。这样,就出现了a与b同时均指向3的情况。定义完a与b的值后,再令a = 4;那么,b不会等于4,还是等于3。在编译器内部,遇到时,它就会重新搜索栈中是否有4的字面值,如果没有,重新开辟地址存放4的值;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。b)对象在java中,创建一个对象包括对象的声明和实例化两步,下面用一个例题来说明对象的内存模型。假设有类Rectangle定义如下:1. publicclassRectangle 2. doublewidth;3. doubleheight;4. publicRectangle(doublew,doubleh)5. w =width;6. h =height;7. 8. (1)声明对象时的内存模型用Rectangle rect;声明一个对象rect时,将在栈内存为对象的引用变量rect分配内存空间,但Rectangle的值为空,称rect是一个空对象。空对象不能使用,因为它还没有引用任何”实体”。(2)对象实例化时的内存模型当执行rect=new Rectangle(3,5);时,会做两件事:在堆内存中为类的成员变量width,height分配内存,并将其初始化为各数据类型的默认值;接着进行显式初始化(类定义时的初始化值);最后调用构造方法,为成员变量赋值。返回堆内存中对象的引用(相当于首地址)给引用变量rect,以后就可以通过rect来引用堆内存中的对象了。c)创建多个不同的对象实例一个类通过使用new运算符可以创建多个不同的对象实例,这些对象实例将在堆中被分配不同的内存空间,改变其中一个对象的状态不会影响其他对象的状态。例如:1. Rectangler1=newRectangle(3,5);2. Rectangler2=newRectangle(4,6);此时,将在堆内存中分别为两个对象的成员变量width、height分配内存空间,两个对象在堆内存中占据的空间是互不相同的。如果有:1. Rectangler1=newRectangle(3,5);2. Rectangler2=r1;则在堆内存中只创建了一个对象实例,在栈内存中创建了两个对象引用,两个对象引用同时指向一个对象实例。d)包装类基本类型都有对应的包装类:如int对应Integer类,double对应Double类等,基本类型的定义都是直接在栈中,如果用包装类来创建对象,就和普通对象一样了。例如:int i=0;i直接存储在栈中。Integer i(i此时是对象)= new Integer(5);这样,i对象数据存储在堆中,i的引用存储在栈中,通过栈中的引用来操作对象。e)StringString是一个特殊的包装类数据。可以用以下两种方式创建:String str =newString(“abc”);String str = “abc”;第一种创建方式,和普通对象的的创建过程一样;第二种创建方式,java内部将此语句转化为以下几个步骤:(1)先定义一个名为str的对String类的对象引用变量:String str;(2)在栈中查找有没有存放值为”abc”的地址,如果没有,则开辟一个存放字面值为”abc”地址,接着创建一个新的String类的对象o,并将o的字符串值指向这个地址,而且在栈这个地址旁边记下这个引用的对象o。如果已经有了值为”abc”的地址,则查找对象o,并回o的地址。(3)将str指向对象o的地址。值得注意的是,一般String类中字符串值都是直接存值的。但像String str = “abc”;这种合下,其字符串值却是保存了一个指向存在栈中数据的引用。为了更好地说明这个问题,我们可以通过以下的几个代码进行验证。1. String str1=abc;2. String str2=abc;3. System.out.println(s1=s2);/true注意,这里并不用str1.equals(str2);的方式,因为这将比较两个字符串的值是否相等。=号,根据JD

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论