孙鑫java ppt

简介 相关

截图

孙鑫java ppt

简介

这是孙鑫java ppt,包括了Java的起源,我们为什么要用Java,Java跨平台的原理,Java开发工具包(JDK)的下载,面向对象程序设计,一个简单的例子等内容,欢迎点击下载。

孙鑫java ppt是由红软PPT免费下载网推荐的一款课件PPT类型的PowerPoint.

Java技术与应用 主讲人:孙鑫 Java的起源 我们为什么要用Java 我们为什么要用Java 简单的 Java最初是为对家用电器进行集成控制而设计的一种语言,因此它必须简单明了。Java语言的简单性主要体现在三个方面: 1、Java的风格类似于C++,因而C++程序员初次接触Java语言,就会感到很熟悉。从某种意义上讲,Java语言是C及C++语言的一个变种,因此,C++程序员可以很快地掌握Java编程技术。 2、Java摒弃了C++中容易引发程序错误的一些特性,如指针、结构、枚举以及内存管理等。 3、Java提供了丰富的类库,可以帮助我们很方便的开发Java程序。 我们为什么要用Java 面向对象的 面向对象可以说是Java最重要的特性,所以它支持继承、重载、多态等面向对象的特性。Java语言的设计是完全面向对象的,它不支持类似C语言那样的面向过程的程序设计技术。 我们为什么要用Java 健壮的 Java致力于检查程序在编译和运行时的错误。Java也是一种强类型的语言,其类型检查比C++还要严格。类型检查帮助我们检查出许多开发早期出现的错误。Java自己负责内存管理,提供了垃圾内存回收机制,有效的避免了C++中最头疼的内存泄漏问题。 我们为什么要用Java 安全的 Java的安全性可从两个方面得到保证。一方 面,在Java语言里,删除了指针和释放内存等C++功能,避免了非法内存操作。另一方面,通过Java的安全体系架构来确保Java代码的安全性。当我们从网上下载Java代码在本地执行时,Java的安全架构能确保恶意的代码不能随意访问我们本地计算机的资源,例如:删除文件,访问本地网络资源等操作都是被禁止的。 我们为什么要用Java 解释的 Java代码是解释执行的,我们使用Java编译器将Java代码编译成字节码,这是一种中间代码,然后由Java解释器解释执行。而C++程序是编译执行的,C++程序代码被编译为本地机器指令,然后执行。 我们为什么要用Java 与平台无关的 Java作为一种网络语言,其源代码被编译成一种结构中立的中间文件格式。只要有Java运行系统的机器都能执行这种中间代码。Java源程序被编译成一种与机器无关的字节码格式,在Java虚拟机上运行。 我们为什么要用Java 多线程的 Java语言的一个重要特性就是在语言级支持多线程的程序设计。多线程就好像我们做一张桌子,如果你一个人完成这张桌子—就好像单线程,那么你需要先做桌面,做完桌面后,再做4个桌子腿,如果现在有5个人来做桌子—在程序中开辟5个线程,其中1个人做桌面,另外4个人分别做4个桌子腿,那么这两种方式效率的高低,相信大家都能区分出来。 我们为什么要用Java 动态的 Java的动态特性是其面向对象设计方法的扩展。它允许程序动态地装入运行过程中所需要的类,这是我们采用C++语言进行面向对象程序设计所无法实现的。在C++程序设计过程中,每当在类中增加一个实例变量或一个成员函数后, 引用该类的所有子类都必须重新编译,否则将导致程序崩溃。Java从以下几个方面采取措施来解决这个问题。Java编译器不是将对实例变量和成员函数的引用编译为数值引用,而是将符号引用信息在字节码中保存下来,传递给解释器,再由解释器在完成动态连接类后,将符号引用信息转换为数值偏移量。一个在存储器中生成的对象不在编译过程中决定,而是延迟到运行时由解释器确定。这样,对类中的变量和方法进行更新时就不至于影响现存的代码。 解释执行字节码时,这种符号信息的查找和转换过程仅在一个新的名字出现时才进行一次,随后代码便可以全速执行。在运行时确定引用的好处是可以使用已被更新的类,而不必担心会影响原有的代码。如果程序连接了网络中另一系统中的某一类,该类的所有者也可以自由地对该类进行更新,而不会使任何引用该类的程序崩溃。Java还简化了使用一个升级的或全新协议的方法。如果你的系统运行Java程序时遇到了不知怎样处理的程序,Java能自动下载你所需要的功能程序。 Java跨平台的原理 Java的跨平台是通过Java虚拟机(JVM)来实现的。 Java跨平台的原理 Java源文件的编译过程 Java应用程序的开发周期包括编译、下载、解释和执行几个部分。Java编译程序将Java源程序翻译为JVM可执行代码—字节码。这一编译过程同C/C++的编译有些不同。当C编译器编译生成一个对象的代码时,该代码是为在某一特定硬件平台运行而产生的。因此,在编译过程中,编译程序通过查表将所有对符号的引用转换为特定的内存偏移量,以保证程序运行。Java编译器却不将对变量和方法的引用编译为数值引用,也不确定程序执行过程中的内存布局,而是将这些符号引用信息保留在字节码中,由解释器在运行过程中创建内存布局,然后再通过查表来确定一个方法所在的地址。这样就有效的保证了Java的可移植性和安全性。 Java跨平台的原理 Java解释器的执行过程 运行JVM字节码的工作是由解释器来完成的。解释执行过程分三步进行:代码的装入、代码的校验和代码的执行。装入代码的工作由“类装载器”(class loader)完成。类装载器负责装入运行一个程序需要的所有代码,这也包括程序代码中的类所继承的类和被其调用的类。当类装载器装入一个类时,该类被放在自己的名字空间中。除了通过符号引用自己名字空间以外的类,类之间没有其他办法可以影响其它类。在本台计算机上的所有类都在同一地址空间内,而所有从外部引进的类,都有一个自己独立的名字空间。这使得本地类通过共享相同的名字空间获得较高的运行效率,同时又保证它们与从外部引进的类不会相互影响。当装入了运行程序需要的所有类后,解释器便可确定整个可执行程序的内存布局。解释器为符号引用同特定的地址空间建立对应关系及查询表。通过在这一阶段确定代码的内存布局,Java很好地解决了由超类改变而使子类崩溃的问题,同时也防止了代码对地址的非法访问。 随后,被装入的代码由字节码校验器进行检查。校验器可发现操作数栈溢出,非法数据类型转换等多种错误。通过校验后,代码便开始执行了。 Java跨平台的原理 Java字节码的两种执行方式 1、即时编译方式:解释器先将字节码编译成机器码,然后再执行该机器码。 2、解释执行方式:解释器通过每次解释并执行一小段代码来完成Java字节码程 序的所有操作。   通常采用的是第二种方法。由于JVM规格描述具有足够的灵活性,这使得将字节码翻译为机器代码的工作具有较高的效率。对于那些对运行速度要求较高的应用程序,解释器可将Java字节码即时编译为机器码,从而很好地保证了Java代码的可移植性和高性能。 Java跨平台的原理 JVM规格描述 JVM的设计目标是提供一个基于抽象规格描述的计算机模型,为解释程序开发人员提供很好的灵活性,同时也确保Java代码可在符合该规范的任何系统上运行。JVM对其实现的某些方面给出了具体的定义,特别是对Java可执行代码,即字节码(Bytecode)的格式给出了明确的规格。这一规格包括操作码和操作数的语法和数值、标识符的数值表示方式、以及Java类文件中的Java对象、常量缓冲池在JVM的存储映象。这些定义为JVM解释器开发人员提供了所需的信息和开发环境。Java的设计者希望给开发人员以随心所欲使用Java的自由。 JVM是为Java字节码定义的一种独立于具体平台的规格描述,是Java平台独立性的基础。 Java跨平台的原理 Java程序执行与C/C++程序执行的对比分析 如果把Java源程序想象成我们的C++源程序,Java源程序编译后生成的字节码就相当于C++源程序编译后的80x86的机器码(二进制程序文件),JVM虚拟机相当于80x86计算机系统,Java解释器相当于80x86CPU。在80x86CPU上运行的是机器码,在Java解释器上运行的是Java字节码。 Java解释器相当于运行Java字节码的“CPU”,但该“CPU”不是通过硬件实现的,而是用软件实现的。Java解释器实际上就是特定的平台下的一个应用程序。只要实现了特定平台下的解释器程序,Java字节码就能通过解释器程序在该平台下运行,这是Java跨平台的根本。当前,并不是在所有的平台下都有相应Java解释器程序,这也是Java并不能在所有的平台下都能运行的原因,它只能在已实现了Java解释器程序的平台下运行。 Java开发工具包(JDK)的下载 下载网址:http://java.sun.com Java的面向对象编程 主讲人:孙鑫 面向对象编程概述 简单的说,面向对象编程(Object Oriented Programming,简称OOP)描述的是对象之间的相互作用。 面向对象编程与面向过程编程的区别: 过程化程序设计先确定算法,再确定数据结构;面向对象编程先确定数据结构,再确定运算。 面向过程编程的程序员,习惯于建立数据结构存放数据并定义方法(函数)来操作数据;面向对象编程的程序员则构造一个对象模型,将数据与方法组织在一起。 对象 对象的状态 对象的行为 我们可以把现实世界的事物抽象成对象。 对象一般都有两个特征:状态(state)和行为(behavior)。 软件的对象概念是由现实世界对象抽象而来 。把现实世界对象的状态保存在软件对象的变量中;现实世界对象的行为通过软件对象的方法(函数)来实现。 类和对象 把相似的对象划归成一个类。 在软件中,类,就是一个模板,它定义了通用于一个特定种类的所有对象的状态(变量)和行为(方法)。 类是创建对象的模板,对象是类的实例。 面向对象程序设计 从程序设计的角度看,类是面向对象程序中最基本的程序单元。类实质上定义的是一种数据类型,这种数据类型就是对象类型 。所以我们可以使用类名称来声明对象变量。 声明对象变量之后,还不能使用对象。必须用运算符new创建对象实体之后,才能使用对象。 面向对象编程的难点 掌握面向对象的困难之处在于思路的转换。 我们通常习惯于考虑解决问题的方法,而不是考虑将问题抽象成对象再去解决它。 一个简单的例子 编写一个驾驶汽车的方法 面向过程的程序设计: 编写一个方法,void drivecar(); 面向对象的程序设计: 将一辆汽车看成一个对象,将所有汽车对象的共性抽取出来,设计一个类Car,类中有一个方法void drive(),用Car这个类实例化一个具体的对象car,调用:car.drive()。 类的构造方法 构造方法的名字和类名相同,并且没有返回值。 构造方法主要用于为类的对象定义初始化状态。 我们不能直接调用构造方法,必须通过new关键字来自动调用,从而创建类的实例。 Java的类都要求有构造方法,如果没有定义构造方法,Java编译器会为我们提供一个缺省的构造方法,也就是不带参数的构造方法。 new关键字的作用 为对象分配内存空间。 引起对象构造方法的调用。 为对象返回一个引用。 缺省构造方法 方法的重载(overload) 特殊变量this this变量代表对象本身 当类中有两个同名变量,一个属于类(类的成员变量),而另一个属于某个特定的方法(方法中的局部变量),使用this区分成员变量和局部变量。 使用this简化构造函数的调用。 特殊变量this 关于实例方法和实例数据成员的进一步说明 一个类所有的实例(对象)调用的成员方法在内存中只有一份拷贝,尽管在内存中可能有多个对象,而数据成员在类的每个对象所在内存中都存在着一份拷贝。this变量允许相同的实例方法为不同的对象工作。每当调用一个实例方法时,this变量将被设置成引用该实例方法的特定的类对象。方法的代码接着会与this所代表的对象的特定数据建立关联。 关键字static 静态方法和静态变量是属于某一个类,而不属于类的对象。 静态方法和静态变量的引用直接通过类名引用。 在静态方法中不能调用非静态的方法和引用非静态的成员变量。反之,则可以。 可以用类的对象obj去调用静态的方法method(),如:obj.method()。 常量的定义 使用关键字final定义常量,例如: final double PI=3.1415926; 作为一种约定,在定义常量时,通常采用大写形式。 final常量可以在声明的同时赋初值,也可以在构造函数中赋初值。 为了节省内存,我们通常将常量声明为静态的(static)。 类的继承 理解继承是理解面向对象程序设计的关键。 在Java中,通过关键字extends继承一个已有的类,被继承的类称为父类(超类,基类),新的类称为子类(派生类)。 在Java中,不允许多继承。 方法的覆盖(override) 在子类中定义一个与父类同名、返回类型、参数类型均相同一个方法,称为方法的覆盖。 覆盖发生在子类与父类之间。 特殊变量super 特殊变量super,提供了对父类的访问。 可以使用super访问父类被子类隐藏的变量或覆盖的方法。 每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的构造函数,那么在编译的时候就会报错。 多态性 通过覆盖父类的方法来实现,在运行时根据传递的对象引用,来调用相应的方法。 面向对象的程序设计 问题:求一个长方形的周长和面积。 以面向过程的程序设计方式思考: 1、确定长方形周长和面积的算法。 2、编写两个方法(函数)分别计算长方形的周长和面积。 3、求周长的方法(函数)和求面积的方法(函数)需要两个参数,分别是长方形的长和宽。 面向过程的程序设计代码: class Rectangle { static int perimeter(int length,int width) { return 2*(length+width); } static int area(int length,int width) { return length*width; } public static void main(String[] args) { System.out.println("perimeter = “ + Rectangle.perimeter(5,4)); System.out.println("area = “ + Rectangle.area(5,4)); } } 面向对象的程序设计 问题:求一个长方形的周长和面积。 以面向对象的程序设计方式思考: 1、一个长方形可以看成一个长方形对象。 2、一个长方形对象有两个状态(长和宽)和两个行为(求周长和求面积)。 3、将所有长方形的共性抽取出来,设计一个长方形类。 4、通过长方形对象的行为,就可以求出某个具体的长方形对象的周长和面积。 面向对象的程序设计 Demo Lesson3 主讲人:孙鑫 主要内容 包 类的说明符 方法的说明符 对象的销毁(垃圾内存回收的演示) 接口 内部类和匿名内部类 异常处理 包(package) 为了便于管理大型软件系统中数目众多的类,解决类命名冲突的问题,Java引入了包(package)。 包(package) package语句必须是文件中的第一条语句。也就是说,在package语句之前,除了空白和注释之外不能有任何语句。 如果不加package语句,则指定为缺省包或无名包。 包对应着文件系统的目录层次结构。 在package语句中,用“.”来指明包(目录)的层次。 编译并生成包 在当前目录下生成包 javac –d . Test.java 在指定目录下生成包 javac –d E:\JavaLesson Test.java import语句 引入包中的类。 import java.io.File; 引入整个包。 import java.io.*; 在同一包中的类可以互相引用,无需import语句。 类的说明符 类的访问说明符 (1)public (2)default(不加访问说明符时) 类的其它修饰符 (1)final (2)abstract 方法的说明符 方法的访问说明符 (1)public (2)protected (3)default(不加访问说明符时) (4)private 方法的其它修饰符 (1)static (2)final (3)abstract (4)native (5)synchronized 方法的访问控制 方法的访问控制 方法的访问控制 方法的访问控制 方法的访问控制 final方法 为了确保某个函数的行为在继承过程中保持不变,并且不能被覆盖(overridden),可以使用final方法。 为了效率上的考虑,将方法声明为final,让编译器对此方法的调用进行优化。要注意的是:编译器会自行对final方法进行判断,并决定是否进行优化。通常在方法的体积很小,而我们确实不希望它被覆盖时,才将它声明为final。 class中所有的private和static方法自然就是final。 抽象方法和抽象类 在类中没有方法体的方法,就是抽象方法。 含有抽象方法的类,即为抽象类。 如果一个子类没有实现抽象基类中所有的抽象方法,则子类也成为一个抽象类。 我们可以将一个没有任何抽象方法的类声明为abstract,避免由这个类产生任何的对象。 构造方法、静态方法、私有方法、final方法不能被声明为抽象的方法。 native方法 native方法是用户在Java中可以使用,但不能编写的方法。 JNI(Java Native Interface),它允许Java虚拟机(JVM)内部运行的Java代码能够与用其它编程语言(如C、C++、汇编语言)编写的应用程序和库进行互操作。 JNI最大的好处是它没有对底层Java虚拟机的实现施加任何限制,因此,Java虚拟机厂商可以在不影响虚拟机其它部分的情况下添加对JNI的支持。程序员只需编写一种版本的本地(Native)应用程序和库,就能够与所有支持JNI的Java虚拟机协同工作。 JNI可以理解为Java和本地应用程序之间的中介。 接口 接口中所有的方法都是public abstract。 在接口中声明方法时,不能使用native、static 、final 、synchronized 、private 、protected等修饰符。 和public类一样,public接口也必须定义在与接口同名的文件中。 接口 接口中可以有数据成员,这些成员默认都是public static final。 接口 一个接口可以继承自另一个接口。 Java中不允许类的多继承,但允许接口的多继承。 接口 在Java中,一个类可以实现多个接口。 一个类在继承另外一个类的同时,可以实现多个接口。 内部类 在一个类中定义另外一个类,这个类就叫做内部类或内置类 (inner class) 。 内部类可以让我们将逻辑上相关的一组类组织起来,并由外部类(outer class)来控制内部类的可见性。 当我们建立一个inner class时,其对象就拥有了与外部类对象之间的一种关系,这是通过一个特殊的this reference形成的,使得内部类对象可以随意的访问外部类中所有的成员。 内部类 在方法中定义的内部类,如果要访问方法中定义的本地变量或方法的参数,则变量必须被声明final。 内部类可以声明为private或protected;还可以声明为abstract或final。 内部类可以声明为static的,但此时就不能再使用外部类的非static的成员变量和非static的成员方法; 非static的内部类中的成员不能声明为static的,只有在顶层类或static的内部类中才可声明static成员。 内部类 我们为什么使用内部类 1、在内部类(inner class)中,可以随意的访问外部类的成员,这可以让我们更好地组织管理我们的代码,增强代码的可读性。 2、内部类可以用于创建适配器类,适配器类是用于实现接口的类。使用内部类来实现接口,可以更好地定位与接口关联的方法在代码中的位置。 3、内部类的更多用法。 异常类的层次结构 异常处理 打开一个不存在的文件、网络连接中断、数组下标越界、正在加载的类文件丢失等都会引发异常。 Java中的异常类定义了程序中遇到的轻微的错误条件。 Java中的错误类定义了程序中不能恢复的严重错误条件。如内存溢出、类文件格式错误等。这一类错误由Java运行系统处理,不需要我们去处理。 异常处理 Java程序在执行过程中如出现异常,会自动生成一个异常类对象,该异常对象将被提交给Java运行时系统,这个过程称为抛出(throw)异常。 当Java运行时系统接收到异常对象时,会寻找能处理这一异常的代码并把当前异常对象交给其处理,这一过程称为捕获(catch)异常。 如果Java运行时系统找不到可以捕获异常的方法,则运行时系统将终止,相应的Java程序也将退出。 try/catch/finally语句。 异常处理 对于RuntimeException,通常不需要我们去捕获,这类异常由Java运行系统自动抛出并自动处理。 如果父类中的方法抛出多个异常,则子类中的覆盖方法要么抛出相同的异常,要么抛出异常的子类,但不能抛出新的异常(注:构造方法除外)。 我们可以在方法声明时,声明一个不会抛出的异常,Java编译器就会强迫方法的使用者对异常进行处理。这种方式通常应用于abstract base class和interface中。 Java编程规范 package的命名 package 的名字由全部小写的字母组成,例如:cn.mybole。 class和interface的命名 class和interface的名字由大写字母开头而其他字母都小写的单词组成,例如:Person,RuntimeException。 class变量的命名 变量的名字用一个小写字母开头,后面的单词用大写字母开头,例如:index,currentImage。 class方法的命名 方法的名字用一个小写字母开头,后面的单词用大写字母开头,例如:run(),getBalance()。 static final变量的命名 static final变量的名字所有字母都大写,并且能表示完整含义。例如:PI,PASSWORD。 参数的命名 参数的名字和变量的命名规范一致。 数组的命名 数组应该总是用这样的方式来命名:byte[] buffer。 附:JVM 规格描述 JVM定义了控制Java代码解释执行和具体实现的五种规格 JVM指令系统 JVM寄存器 JVM栈结构 JVM碎片回收堆 JVM存储区 附:JVM 规格描述 JVM指令系统 JVM指令系统同其他计算机的指令系统极其相似。Java指令也是由操作码和操作数两部分组成。操作码为8位二进制数,操作数紧随在操作码的后面,其长度根据需要而不同。操作码用于指定一条指令操作的性质(在这里我们采用汇编符号的形式进行说明),如iload表示从存储器中装入一个整数,anewarray表示为一个新数组分配空间,iand表示两个整数的“与”,ret用于流程控制,表示从对某一方法的调用中返回。当长度大于8位时,操作数被分为两个以上字节存放。JVM采用了“big endian”的编码方式来处理这种情况,即高位bits存放在低字节中。这同 Motorola及其他的RISC CPU采用的编码方式是一致的,而与Intel采用的“little endian ”的编码方式即低位bits存放在低位字节的方法不同。   Java指令系统是以Java语言的实现为目的设计的,其中包含了用于调用方法和监视多线程系统的指令。 附:JVM 规格描述 JVM寄存器 所有的CPU均包含用于保存系统状态和处理器所需信息的寄存器组。如果虚拟机定义较多的寄存器,便可以从中得到更多的信息而不必对栈或内存进行访问,这有利于提高运行速度。然而,如果虚拟机中的寄存器比实际CPU的寄存器多,在实现虚拟机时就会占用处理器大量的时间来用常规存储器模拟寄存器,这反而会降低虚拟机的效率。针对这种情况,JVM只设置了4个最为常用的寄存器。它们是:   pc程序计数器   optop操作数栈顶指针   frame当前执行环境指针   vars指向当前执行环境中第一个局部变量的指针 所有寄存器均为32位。pc用于记录程序的执行。optop,frame和vars用于记录指向Java栈区的指针。 附:JVM 规格描述 JVM栈结构 作为基于栈结构的计算机,Java栈是JVM存储信息的主要方法。当JVM得到一个Java字节码应用程序后,便为该代码中一个类的每一个方法创建一个栈框架,以保存该方法的状态信息。每个栈框架包括以下三类信息:   局部变量   执行环境   操作数栈 局部变量用于存储一个类的方法中所用到的局部变量。vars寄存器指向该变量表中的第一个局部变量。   执行环境用于保存解释器对Java字节码进行解释过程中所需的信息。它们是:上次调用的方法、局部变量指针和操作数栈的栈顶和栈底指针。执行环境是执行一个方法的控制中心。例如:如果解释器要执行iadd(整数加法),首先要从frame寄存器中找到当前执行环境,而后便从执行环境中找到操作数栈,从栈顶弹出两个整数进行加法运算,最后将结果压入栈顶。 操作数栈用于存储运算所需操作数及运算的结果。 附:JVM 规格描述 JVM碎片回收堆 Java类的实例(对象)所需的存储空间是在堆上分配的。解释器具体承担为类实例分配空间的工作。解释器在为一个实例分配完存储空间后,便开始记录对该实例所占用的内存区域的使用。一旦对象使用完毕,便将其回收到堆中。 在Java语言中,除了new语句外没有其他方法为一对象申请和释放内存。对内存进行释放和回收的工作是由Java运行系统承担的。这允许Java运行系统的设计者自己决定碎片回收的方法。在SUN公司开发的Java解释器和Hot Java环境中,碎片回收用后台线程的方式来执行。这不但为运行系统提供了良好的性能,而且使程序设计人员摆脱了自己控制内存使用的风险。 附:JVM 规格描述 JVM存储区 JVM有两类存储区:常量缓冲池和方法区。常量缓冲池用于存储类名称、方法和字段名称以及串常量。方法区则用于存储Java方法的字节码。对于这两种存储区域具体实现方式在JVM规格中没有明确规定。这使得Java应用程序的存储布局必须在运行过程中确定,依赖于具体平台的实现方式。 Lesson4 主讲人:孙鑫 主要内容 Java的常用包 “==”和“equals”的用法 基本数据类型与引用类型 String和StringBuffer 对象的克隆(clone) 数组的相关操作 封装类 Runtime类与Process类 Class类 设计模式 Java的常用包 java.applet:包含一些用于创建Java小应用程序的类。 java.awt:包含一些用于编写与平台无关的图形界面(GUI)应用程序的类。 java.io:包含一些用作输入输出(I/O)处理的类。 java.lang:包含一些Java语言的基本类与核心类,如String、Math、Integer、System和Runtime,提供常用的功能,这个包中的所有类是被隐式导入的。 java.net:包含用于建立网络连接的类,与java.io同时使用完成与网络有关的读写。 java.util:包含一些实用工具类和数据结构类。 “==”和“equals”的用法 在Java中,boolean、byte、short、int、long、char、float、double这八种是基本数据类型,其余的都是引用类型。 “==”是比较两个变量的值是否相等,“equals”是比较两个对象变量所代表的对象的内容是否相等。 对象的内存分配图 String和StringBuffer String str=“abc”; int i=3; float f=4.5f; char ch='a'; boolean b=true; System.out.println(str + i + f + ch + b); 针对String的“+”和“+=”,是Java中唯一被重载的操作符;在Java中,不允许程序员重载操作符。 String和StringBuffer String类对象一个常量对象。 String str=“abc”; str=“def”; 在处理大量字符串的程序中,我们通常用StringBuffer来替代String。 数组的内存分配图 基本数据类型一维数组内存分配 数组的内存分配图 基本数据类型一维数组内存分配 对象数组的内存分配 对象数组的内存分配 对象数组的内存分配 函数的调用 在Java中,传参时,都是以传值的方式进行。 对于基本数据类型,传递的是数据的拷贝;对于引用类型,传递的引用的拷贝。 函数的调用 函数的调用 对象的克隆(clone) 为了获取对象的一份拷贝,我们可以利用Object类的clone()方法。 在派生类中覆盖基类的clone()方法,并声明为public。 在派生类的clone()方法中,调用super.clone()。 在派生类中实现Cloneable接口。 对象的克隆(clone) 为什么我们在派生类中覆盖Object的clone()方法时,一定要调用super.clone()呢?在运行时刻,Object中的clone()识别出你要复制的是哪一个对象,然后为此对象分配空间,并进行对象的复制,将原始对象的内容一一复制到新对象的存储空间中。 数组的相关操作 在Java中,所有的数组都有一个缺省的属性length,用于获取数组中元素的个数。 数组的复制:System.arraycopy()。 数组的排序:Arrays.sort()。 在已排序的数组中查找某个元素:Arrays.binarySearch()。 封装类 针对八种基本数据类型定义的相应的引用类型-封装类。 Class类 在Java中,每个class都有一个相应的Class对象。也就是说,当我们编写一个类,编译完成后,在生成的.class文件中,就会产生一个Class对象,用于表示这个类的类型信息。 获取Class实例的三种方式: (1)利用对象调用getClass()方法获取该对象的Class实例; (2)使用Class类的静态方法forName(),用类的名字获取一个Class实例; (3)运用.class的方式来获取Class实例,对于基本数据类型的封装类,还可以采用.TYPE来获取相对应的基本数据类型的Class实例。 Class类 在运行期间,如果我们要产生某个类的对象,Java虚拟机(JVM)会检查该类型的Class对象是否已被加载。如果没有被加载,JVM会根据类的名称找到.class文件并加载它。一旦某个类型的Class对象已被加载到内存,就可以用它来产生该类型的所有对象。 newInstance() 调用类中缺省的构造方法。 Runtime类和Process类 每一个Java程序都有一个Runtime类的单一实例。 通过Runtime.getRuntime()获取Runtime类的实例。 Runtime类是使用单例模式的一个例子。 设计模式 在我们进行程序设计时,逐渐形成了一些典型问题和问题的解决方案,这就是软件模式。 每一个模式描述了一个在我们程序设计中经常发生的问题,以及该问题的解决方案。 当我们碰到模式所描述的问题,就可以直接用相应的解决方法去解决这个问题,这就是设计模式。 设计模式 单例(Singleton)模式 (1)一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类。 (2)单例类的一个最重要的特点是类的构造方法是私有的,从而避免了外部利用构造方法直接创建多个实例。 单例类的实现 Lesson5 多线程 主讲人:孙鑫 程序、进程和线程 程序是计算机指令的集合,它以文件的形式存储在磁盘上。 进程:是一个程序在其自身的地址空间中的一次执行活动。 进程是资源申请、调度和独立运行的单位,因此,它使用系统中的运行资源;而程序不能申请系统资源,不能被系统调度,也不能作为独立运行的单位,因此,它不占用系统的运行资源。 线程:是进程中的一个单一的连续控制流程。一个进程可以拥有多个线程。 线程又称为轻量级进程,它和进程一样拥有独立的执行控制,由操作系统负责调度,区别在于线程没有独立的存储空间,而是和所属进程中的其它线程共享一个存储空间,这使得线程间的通信远较进程简单。 单线程程序与多线程程序 Java对多线程的支持 Java在语言级提供了对多线程程序设计的支持。 实现多线程程序的两种方式: (1)从Thread类继承; (2)实现Runnable接口。 Java对多线程的支持 Java运行时系统实现了一个用于调度线程执行的线程调度器,用于确定某一时刻由哪一个线程在CPU上运行。 在java技术中,线程通常是抢占式的而不需要时间片分配进程(分配给每个线程相等的CPU时间的进程)。抢占式调度模型就是许多线程处于可以运行状态(等待状态),但实际上只有一个线程在运行。该线程一直运行到它终止进入可运行状态(等待状态),或者另一个具有更高优先级的线程变成可运行状态。在后一种情况下,低优先级的线程被高优先级的线程抢占,高优先级的线程获得运行的机会。 Java线程调度器支持不同优先级线程的抢先方式,但其本身不支持相同优先级线程的时间片轮换。 Java运行时系统所在的操作系统(例如:Windows2000)支持时间片的轮换,则线程调度器就支持相同优先级线程的时间片轮换。 线程的同步 The code segments within a program that access the same object from separate, concurrent threads are called “critical sections”。 同步的两种方式:同步块和同步方法 每一个对象都有一个监视器,或者叫做锁。 同步方法利用的是this所代表的对象的锁。 每个class也有一个锁,是这个class所对应的Class对象的锁。 线程的死锁 哲学家进餐的问题 线程1锁住了对象A的监视器,等待对象B的监视器,线程2锁住了对象B的监视器,等待对象A的监视器,就造成了死锁。 wait、notify、notifyAll 每一个对象除了有一个锁之外,还有一个等待队列(wait set),当一个对象刚创建的时候,它的对待队列是空的。 我们应该在当前线程锁住对象的锁后,去调用该对象的wait方法。 当调用对象的notify方法时,将从该对象的等待队列中删除一个任意选择的线程,这个线程将再次成为可运行的线程。 当调用对象的notifyAll方法时,将从该对象的等待队列中删除所有等待的线程,这些线程将成为可运行的线程。 wait和notify主要用于producer-consumer这种关系中。 线程的状态 线程的终止 设置一个flag变量。 结合interrupt()方法。 Java Language Specification 网址:http://java.sun.com/docs/books/jls/second_edition/html/jTOC.doc.html Lesson6 集合类 主讲人:孙鑫 集合框架中的接口 集合框架中的接口 Collection:集合层次中的根接口,JDK没有提供这个接口直接的实现类。 Set:不能包含重复的元素。SortedSet是一个按照升序排列元素的Set。 List:是一个有序的集合,可以包含重复的元素。提供了按索引访问的方式。 Map:包含了key-value对。Map不能包含重复的key。SortedMap是一个按照升序排列key的Map。 集合框架中的实现类 ArrayList ArrayList:我们可以将其看作是能够自动增长容量的数组。 利用ArrayList的toArray()返回一个数组。 Arrays.asList()返回一个列表。 迭代器(Iterator) 给我们提供了一种通用的方式来访问集合中的元素。 迭代器的工作原理 Collections类 排序:Collections.sort() (1)自然排寻(natural ordering ); (2)实现比较器(Comparator)接口。 取最大和最小的元素:Collections.max()、Collections.min()。 在已排序的List中搜索指定的元素:Collectons.binarySearch()。 LinkedList LinkedList是采用双向循环链表实现的。 利用LinkedList实现栈(stack)、队列(queue)、双向队列(double-ended queue )。 数据结构 一般将数据结构分为两大类:线性数据结构和非线性数据结构。线性数据结构有线性表、栈、队列、串、数组和文件;非线性数据结构有树和图。 线性表 线性表的逻辑结构是n个数据元素的有限序列: (a1, a2 ,a3,…an) n为线性表的长度(n≥0),n=0的表称为空表。 数据元素呈线性关系。必存在唯一的称为“第一个”的数据元素;必存在唯一的称为“最后一个”的数据元素;除第一个元素外,每个元素都有且只有一个前驱元素; 除最后一个元素外,每个元素都有且只有一个后继元素。 所有数据元素在同一个线性表中必须是相同的数据类型。 线性表 线性表按其存储结构可分为顺序表和链表。用顺序存储结构存储的线性表称为顺序表;用链式存储结构存储的线性表称为链表。 将线性表中的数据元素依次存放在某个存储区域中,所形成的表称为顺序表。一维数组就是用顺序方式存储的线性表。 链表 单向链表 链表 链表 循环链表 链表 双向循环链表 栈 栈(Stack)也是一种特殊的线性表,是一种后进先出(LIFO)的结构。 栈是限定仅在表尾进行插入和删除运算的线性表,表尾称为栈顶(top),表头称为栈底(bottom)。 栈的物理存储可以用顺序存储结构,也可以用链式存储结构。 队列 队列(Queue)是限定所有的插入只能在表的一端进行,而所有的删除都在表的另一端进行的线性表。 表中允许插入的一端称为队尾(Rear),允许删除的一端称为队头(Front)。 队列的操作是按先进先出(FIFO)的原则进行的。 队列的物理存储可以用顺序存储结构,也可以用链式存储结构。 ArrayList和LinkedList的比较 ArrayList底层采用数组完成,而LinkedList则是以一般的双向链表(double-linked list)完成,其内每个对象除了数据本身外,还有两个 引用,分别指向前一个元素和后一个元素。 如果我们经常在List的开始处增加元素,或者在List中进行插入和删除操作,我们应该使用LinkedList,否则的话,使用ArrayList将更加快速。 HashSet 实现Set接口的hash table(哈希表),依靠HashMap来实现的。 我们应该为要存放到散列表的各个对象定义hashCode()和equals()。 散列表 散列表又称为哈希表。散列表算法的基本思想是: 以结点的关键字为自变量,通过一定的函数关系(散列函数)计算出对应的函数值,以这个值作为该结点存储在散列表中的地址。 当散列表中的元素存放太满,就必须进行再散列,将产生一个新的散列表,所有元素存放到新的散列表中,原先的散列表将被删除。在Java语言中,通过负载因子(load factor)来决定何时对散列表进行再散列。例如:如果负载因子是0.75,当散列表中已经有75%的位置已经放满,那么将进行再散列。 负载因子越高(越接近1.0),内存的使用效率越高,元素的寻找时间越长。负载因子越低(越接近0.0),元素的寻找时间越短,内存浪费越多。 HashSet类的缺省负载因子是0.75。 TreeSet TreeSet是依靠TreeMap来实现的。 TreeSet是一个有序集合,TreeSet中元素将按照升序排列,缺省是按照自然顺序进行排列,意味着TreeSet中元素要实现Comparable接口。 我们可以在构造TreeSet对象时,传递实现了Comparator接口的比较器对象。 HashSet和TreeSet的比较 HashSet是基于Hash算法实现的,其性能通常都优于TreeSet。我们通常都应该使用HashSet,在我们需要排序的功能时,我们才使用TreeSet。 HashMap HashMap对key进行散列。 keySet()、values()、entrySet()。 TreeMap TreeMap按照key进行排序。 HashMap和TreeMap的比较 和Set类似,HashMap的速度通常都比TreeMap快,只有在需要排序的功能的时候,才使用TreeMap。 Java1.0/1.1的集合类 Vector:用ArrayList代替Vector。 Hashtable:用HashMap代替Hashtable。 Satck:用LinkedList代替Stack。 Properties Lesson7 I/O 主讲人:孙鑫 File类 一个File类的对象,表示了磁盘上的文件或目录。 File类提供了与平台无关的方法来对磁盘上的文件或目录进行操作。 流式I/O 流(Stream)是字节的源或目的。 两种基本的流是:输入流(Input Stream)和输出流(Output Stream)。可从中读出一系列字节的对象称为输入流。而能向其中写入一系列字节的对象称为输出流。 流的分类 节点流:从特定的地方读写的流类,例如:磁盘或一块内存区域。 过滤流:使用节点流作为输入或输出。过滤流是使用一个已经存在的输入流或输出流连接创建的。 InputStream 三个基本的读方法 abstract int read() :读取一个字节数据,并返回读到的数据,如果返回-1,表示读到了输入流的末尾。 int read(byte[] b) :将数据读入一个字节数组,同时返回实际读取的字节数。如果返回-1,表示读到了输入流的末尾。 int read(byte[] b, int off, int len) :将数据读入一个字节数组,同时返回实际读取的字节数。如果返回-1,表示读到了输入流的末尾。off指定在数组b中存放数据的起始偏移位置;len指定读取的最大字节数。 其它方法 long skip(long n) :在输入流中跳过n个字节,并返回实际跳过的字节数。 int available() :返回在不发生阻塞的情况下,可读取的字节数。 void close() :关闭输入流,释放和这个流相关的系统资源。 void mark(int readlimit) :在输入流的当前位置放置一个标记,如果读取的字节数多于readlimit设置的值,则流忽略这个标记。 void reset() :返回到上一个标记。 boolean markSupported() :测试当前流是否支持mark和reset方法。如果支持,返回true,否则返回false。 java.io包中 InputStream的类层次 OutputStream 三个基本的写方法 abstract void write(int b) :往输出流中写入一个字节。 void write(byte[] b) :往输出流中写入数组b中的所有字节。 void write(byte[] b, int off, int len) :往输出流中写入数组b中从偏移量off开始的len个字节的数据。 其它方法 void flush() :刷新输出流,强制缓冲区中的输出字节被写出。 void close() :关闭输出流,释放和这个流相关的系统资源。 java.io包中 OutputStream的类层次 基本的流类 FileInputStream和FileOutputStream 节点流,用于从文件中读取或往文件中写入字节流。如果在构造FileOutputStream时,文件已经存在,则覆盖这个文件。 BufferedInputStream和BufferedOutputStream 过滤流,需要使用已经存在的节点流来构造,提供带缓冲的读写,提高了读写的效率。 DataInputStream和DataOutputStream 过滤流,需要使用已经存在的节点流来构造,提供了读写Java中的基本数据类型的功能。 PipedInputStream和PipedOutputStream 管道流,用于线程间的通信。一个线程的PipedInputStream对象从另一个线程的PipedOutputStream对象读取输入。要使管道流有用,必须同时构造管道输入流和管道输出流。 Java I/O库的设计原则 Java的I/O库提供了一个称做链接的机制,可以将一个流与另一个流首尾相接,形成一个流管道的链接。这种机制实际上是一种被称为Decorator(装饰)设计模式的应用。 通过流的链接,可以动态的增加流的功能,而这种功能的增加是通过组合一些流的基本功能而动态获取的。 我们要获取一个I/O对象,往往需要产生多个I/O对象,这也是Java I/O库不太容易掌握的原因,但在I/O库中Decorator模式的运用,给我们提供了实现上的灵活性。 I/O流的链接 Reader和Writer Java程序语言使用Unicode来表示字符串和字符。 Reader和Writer这两个抽象类主要用来读写字符流。 java.io包中Reader的类层次 java.io包中Writer的类层次 字符集的编码 ASCII(American Standard Code for Information Interchange,美国信息互换标准代码),是基于常用的英文字符的一套电脑编码系统。我们知道英文中经常使用的字符、数字符号被计算机处理时都是以二进制码的形式出现的。这种二进制码的集合就是所谓的ASCII码。每一个ASCII码与一个8位(bit)二进制数对应。其最高位是0,相应的十进制数是0-127。如,数字“0”的编码用十进制数表示就是48。另有128个扩展的ASCII码,最高位都是1,由一些制表符和其它符号组成。ASCII是现今最通用的单字节编码系统。 GB2312:GB2312码是中华人民共和国国家汉字信息交换用编码,全称《信息交换用汉字编码字符集-基本集》。主要用于给每一个中文字符指定相应的数字,也就是进行编码。一个中文字符用两个字节的数字来表示,为了和ASCII码有所区别,将中文字符每一个字节的最高位置都用1来表示。 GBK:为了对更多的字符进行编码,国家又发布了新的编码系统GBK(GBK的K是“扩展”的汉语拼音第一个字母)。在新的编码系统里,除了完全兼容GB2312 外,还对繁体中文、一些不常用的汉字和许多符号进行了编码。 ISO-8859-1:是西方国家所使用的字符编码集,是一种单字节的字符集 ,而英文实际上只用了其中数字小于128的部分。 字符集的编码 Unicode:这是一种通用的字符集,对所有语言的文字进行了统一编码,对每一个字符都用2个字节来表示,对于英文字符采取前面加“0”字节的策略实现等长兼容。如 “a” 的ASCII码为0x61,UNICODE就为0x00,0x61。 UTF-8:Eight-bit UCS Transformation Format,(UCS,Universal Character Set,通用字符集,UCS 是所有其他字符集标准的一个超集)。一个7位的ASCII码值,对应的UTF码是一个字节。如果字符是0x0000,或在0x0080与0x007f之间,对应的UTF码是两个字节,如果字符在0x0800与0xffff之间,对应的UTF码是三个字节。 RandomAccessFile RandomAccessFile类同时实现了DataInput和DataOutput接口,提供了对文件随机存取的功能,利用这个类可以在文件的任何位置读取或写入数据。 RandomAccessFile类提供了一个文件指针,用来标志要进行读写操作的下一数据的位置。 对象序列化 将对象转换为字节流保存起来,并在日后还原这个对象,这种机制叫做对象序列化。 将一个对象保存到永久存储设备上称为持续性。 一个对象要想能够实现序列化,必须实现Serializable接口或Externalizable接口。 对象序列化 当一个对象被序列化时,只保存对象的非静态成员变量,不能保存任何的成员方法和静态的成员变量。 如果一个对象的成员变量是一个对象,那么这个对象的数据成员也会被保存。 如果一个可序列化的对象包含对某个不可序列化的对象的引用,那么整个序列化操作将会失败,并且会抛出一个NotSerializableException。我们可以将这个引用标记为transient,那么对象仍然可以序列化。 总结 InputStream和OutputStream:字节流的输入输出。 Reader和Writer:字符流的输入输出。 流的链接(Java I/O库的设计原则) Java图形界面编程 主讲人:孙鑫 AWT AWT(Abstract Window Toolkit),抽象窗口工具包,SUN公司提供的用于图形界面编程(GUI)的类库。基本的AWT库处理用户界面元素的方法是把这些元素的创建和行为委托给每个目标平台上(Windows、Unix、Macintosh等)的本地GUI工具进行处理。例如:如果我们使用AWT在一个Java窗口中放置一个按钮,那么实际上使用的是一个具有本地外观和感觉的按钮。这样,从理论上来说,我们所编写的图形界面程序能运行在任何平台上,做到了图形界面程序的跨平台运行。 布局管理器 容器里组件的位置和大小是由布局管理器来决定的。容器对布局管理器的特定实例保持一个引用。当容器需要定位一个组件时,它将调用布局管理器来完成。当决定一个组件的大小时,也是如此。 在AWT中,给我们提供了五种布局管理器:BorderLayout FlowLayout GridLayout CardLayout GridBagLayout 布局管理器 我们可以通过设置空布局管理器,来控制组件的大小和位置。调用setLayout(null)。 在设置空布局管理器后,必须对所有的组件调用setLocation(),setSize()或setBounds(),将它们定位在容器中。 网络编程 主讲人:孙鑫 计算机网络 计算机网络是相互连接的独立自主的计算机的集合,最简单的网络形式由两台计算机组成。 两台计算机通过网络进行通信 IP地址 IP网络中每台主机都必须有一个惟一的IP地址; IP地址是一个逻辑地址; 因特网上的IP地址具有全球唯一性; 32位,4个字节,常用点分十进制的格式表示,例如:192.168.0.16 协议 为进行网络中的数据交换(通信)而建立的规则、标准或约定。(=语义+语法+规则) 不同层具有各自不同的协议。 网络的状况 多种通信媒介——有线、无线…… 不同种类的设备——通用、专用…… 不同的操作系统——Unix、Windows …… 不同的应用环境——固定、移动…… 不同业务种类——分时、交互、实时…… 宝贵的投资和积累——有形、无形…… 用户业务的延续性——不允许出现大的跌宕起伏。 它们互相交织,形成了非常复杂的系统应用环境。 网络异质性问题的解决 网络体系结构就是使这些用不同媒介连接起来的不同设备和网络系统在不同的应用环境下实现互操作性,并满足各种业务需求的一种粘合剂,它营造了一种“生存空间” —— 任何厂商的任何产品、以及任何技术只要遵守这个空间的行为规则,就能够在其中生存并发展。 网络体系结构解决异质性问题采用的是分层方法 —— 把复杂的网络互联问题划分为若干个较小的、单一的问题,在不同层上予以解决。 就像我们在编程时把问题分解为很多小的模块来解决一样。 ISO/OSI七层参考模型 OSI(Open System Interconnection)参考模型将网络的不同功能划分为7层。 ISO/OSI七层参考模型 通信实体的对等层之间不允许直接通信。 各层之间是严格单向依赖。 上层使用下层提供的服务 — Service user; 下层向上层提供服务 — Service provider。 对等通信示例 对等层通信的实质 对等层实体之间虚拟通信。 下层向上层提供服务,实际通信在最底层完成。 OSI各层所使用的协议 应用层:远程登录协议Telnet、文件传输协议FTP、 超文本传输协议HTTP、域名服务DNS、简单邮件传输协议SMTP、邮局协议POP3等。 传输层:传输控制协议TCP、用户数据报协议UDP。 TCP:面向连接的可靠的传输协议。 UDP:是无连接的,不可靠的传输协议。 网络层:网际协议IP、Internet互联网控制报文协议ICMP、Internet组管理协议IGMP。 数据封装 一台计算机要发送数据到另一台计算机,数据首先必须打包,打包的过程称为封装。 封装就是在数据前面加上特定的协议头部。 数据封装 OSI参考模型中,对等层协议之间交换的信息单元统称为协议数据单元(PDU,Protocol Data Unit)。 OSI参考模型中每一层都要依靠下一层提供的服务。 为了提供服务,下层把上层的PDU作为本层的数据封装,然后加入本层的头部(和尾部)。头部中含有完成数据传输所需的控制信息。 这样,数据自上而下递交的过程实际上就是不断封装的过程。到达目的地后自下而上递交的过程就是不断拆封的过程。由此可知,在物理线路上传输的数据,其外面实际上被包封了多层“信封”。 但是,某一层只能识别由对等层封装的“信封”,而对于被封装在“信封”内部的数据仅仅是拆封后将其提交给上层,本层不作任何处理。 TCP/IP模型 TCP/IP起源于美国国防部高级研究规划署(DARPA)的一项研究计划——实现若干台主机的相互通信。 现在TCP/IP已成为Internet上通信的工业标准。 TCP/IP模型包括4个层次: 应用层 传输层 网络层 网络接口 TCP/IP与OSI参考模型的对应关系 端口 端口是一种抽象的软件结构(包括一些数据结构和I/O缓冲区)。应用程序通过系统调用与某端口建立连接(binding)后,传输层传给该端口的数据都被相应的进程所接收,相应进程发给传输层的数据都通过该端口输出。 端口用一个整数型标识符来表示,即端口号。端口号跟协议相关,TCP/IP传输层的两个协议TCP和UDP是完全独立的两个软件模块,因此各自的端口号也相互独立,端口通常称为协议端口(protocol port) ,简称端口。 端口使用一个16位的数字来表示,它的范围是0~65535,1024以下的端口号保留给预定义的服务。例如:http使用80端口。 套接字(socket)的引入 为了能够方便的开发网络应用软件,由美国伯克利大学在Unix上推出了一种应用程序访问通信协议的操作系统调用socket(套接字)。socket的出现,使程序员可以很方便地访问TCP/IP,从而开发各种网络应用的程序。 随着Unix的应用推广,套接字在编写网络软件中得到了极大的普及。后来,套接字又被引进了Windows等操作系统中。Java语言也引入了套接字编程模型。 基于TCP的socket编程 基于UDP的socket编程 URL与URI URL(Uniform Resource Locator ),通用资源定位符。http://www.mybole.com.cn/index.asp就是一个URL。 URI(Uniform Resource Identifier),通用资源标识符。 URI纯粹是个符号结构,用于指定构成Web资源的字符串的各个不同部分。URL是一种特殊类型的URI,它包含了用于查找某个资源的足够信息。其它的URI,例如:mailto:myoble@mybole.com.cn则不属于定位符,因为它里面不存在根据该标识符来查找的任何数据。这种URI称为URN(通用资源名)。 在Java库中,URI类不包含用于访问通用资源标识符设定的任何方法,它的唯一作用是进行分析。相反,URL类则可以打开到达资源的一个字符串。kNq红软基地

展开

同类推荐

热门PPT

相关PPT