点击目录传送ฅʕ•̫͡•ʔฅ
- 第1章 初识Java
- 第2章 初识对象和简单数据类型
- 第3章 运算符、表达式和语句
- 第4章 类与对象
- 第5章 子类与继承
- 第6章 接口与多态
- 第7章 数组与枚举
- 第8章 内部类与异常类
- 第9章 常用实用类
- 第10章 输入、输出流
- 第11章 JDBC操作Derby数据库
- 第12章 泛型与集合框架
- 第13章 Java多线程机制
- 第14章 Java网络编程
- 第15章 Java图形用户界面设计 (无)
- 值得记的
第1章 初识Java
-
Java最大优势,就是所谓的 平台无关性
这里所指的 平台是由操作系统(OS)和处理器(CPU)组成的
与平台无关是指 软件的运行不因操作系统、处理器的变化导致发生无法运行或出现运行错误 -
编写一次,到处运行(Write once, run anywhere)
-
三种平台,JavaME 最小,JavaEE 包含 JavaSE,JavaSE 提供了 JDK(Java Development Kit),JDK1.8 就是 JDK8.0
-
JDK,包含 JRE,和编译器、调试器等开发工具
-
Java 可以在平台之上,提供一个 Java 运行环境(Java Runtime Environment)
JRE,由 Java虚拟机(Java Virtual Machine)、类库以及一些核心文件组成。
JVM 的核心就是字节码指令(0,1组成的序列代码,不过不是机器指令,因为它不能被任何平台直接识别、执行),字节码文件就是扩展名为.class
的文件
Java 编译器把 Java 源程序(扩展名为.java
)编译为字节码,可以被 JVM 识别、执行
JVM 负责解释运行字节码,就是将字节码翻译成 JVM 所在平台的机器码,再让当前平台运行该机器码 -
Java 的出现标志着真正的分布式系统的到来
-
Java 集成开发环境 ( IDE ),包括 Eclipse 等
-
安装 JDK 时,建议更改 jdk 默认安装路径,不改 jre 默认安装路径,二者路径不能相同
安装 JDK 时,计算机就安装上了 Java 运行环境 -
JDK 的
bin
子目录中,有编译器(javac.exe)、解释器(java.exe)
jre
子目录中,有JRE
include
子目录中,有C头文件
db
子目录中的lib
子目录中,有 Derby 数据库
根目录中的src.zip
文件是 Java 核心 API 的所有类的 Java 编程语言源文件 -
为了能在任何目录中使用编译器和解释器,应在系统特性中设置 path(配置环境变量)
-
类库帮助文档(Java SE 8 Documentation)
-
Java 应用程序,由若干个 Java源文件 组成 (扩展名为
.java
,源文件名和类名相同),
一个源文件中可以有多个类;主类,包含有 main 方法的类 -
基于对象的编程更符合人的思维模式,使人们更容易解决复杂的问题
-
Java内置支持多线程,即允许同时完成多个任务,这其实是切换过快的错觉,目前处理器在同一时刻只能执行一个线程
-
链接:【Java】第1章 上机实践与习题.
-
链接:配置java环境变量的作用是什么?.
第2章 初识对象和简单数据类型
-
面向对象的一个重要思想就是通过抽象得到类,即将某些数据以及针对这些数据上的操作封装在一个类中,也就是说,抽象的关键有两点:
一是数据(也称属性),二是数据上的操作(也称行为) -
类体
由两部分构成,
一部分是 变量的声明,称为 域变量或成员变量,用来刻画属性;
另一部分是 方法的定义(函数),用来刻画行为 -
用类 创建对象
需经过2个步骤:
1.声明对象(用类声明的变量就称为一个对象)
2.为对象分配变量(new
是为对象分配变量的运算符) -
new 为类中声明的域变量分配内存空间,
分配内存后,将返回一个引用(包含所分配的变量的有关内存地址等信息) -
一个类可以创建多个不同的对象,这些对象将被分配不同的变量(每个对象对应类中的成员变量的内存空间是互不相同的位置)
-
抽象的目的是产生类,而类的目的是创建具有属性和行为的对象
程序可以让对象操作自己的变量改变状态,也可以让对象 调用类中的方法 体现其行为 -
一个Java应用程序由若干个类构成,即由若干个字节码文件构成;
Java应用程序总是从主类的main
方法开始执行;
一般一个类一个源文件,即一个.class
对应一个.java
;
Java 允许在一个 Java 源文件中编写多个类,但至多只能有一个类用public
修饰
源文件名字必须与public
修饰的类的名字完全相同,源文件中没有public
修饰的类则随意与其中一个类名相同即可
编译生成的字节码文件的名字与对应类的名字相同 -
标识符,就是一个名字,是有效字符序列
-
Unicode字符集,最多可以识别 65536 个字符,其前 128 个字符刚好是 ASCII码表
-
简单数据类型也称基本数据类型,8种
分为四大类型,逻辑(boolean
)、字符(char
)、
整数(byte
、short
、int
、long
)、浮点(float
、double
); -
char
型变量,内存分配两个字节,占16位,无符号位,取值范围0~65535,(是不是和Unicode字符集一一对应?😃) -
执行 Scanner 类的输入方法时,会堵塞,等待输入然后 Enter 确认
-
%m.nf
:输出的浮点型数据占 m 列,小数点保留 n 位(格式化输出printf
) -
代码块:用一对大括号括起来的若干内容(链接:Allmans 风格和 Kernighan 风格.)
-
链接:【Java】第2章 上机实践与习题.
第3章 运算符、表达式和语句
-
二目运算符,连接两个操作元的运算符
-
++x
,单目运算符,表示先增1
,再引用 x -
若表达式中最高精度低于
int
型整数,则按int
精度进行运算 -
短路逻辑运算符,例如
&&
、||
等 -
instanceof 运算符,
左操作元是一个对象,右边是一个类(我一直以为是个方法。。。) -
空语句,只有一个分号
-
if-else
的花括号最好不要省略 -
习题
- 1.结果110,规范
- 2.
"不正歪!\0"
- 3.链接:第三章 上机实践与习题答案.
-
竟然忘了 Java 中表示16进制加前缀
0x
,八进制加前缀0
,确实不知道,惭愧
第4章 类与对象
-
面向对象的第一个重要特性:封装
-
抽象的关键是抓住事物的,属性和行为
-
抽象的目的是从具体的实例中抽取共有属性和行为形成一种数据类型
-
类封装了一类对象的属性和行为,类是一种数据类型
-
类的实现 包括,类声明 + 类体
类声明 = class关键字 + 类名(必须是合法的Java标识符)
写类的目的是,根据抽象描述一类事物共有的属性和行为,从而给出一种数据类型,描述过程由类体来实现
类体 = 变量的声明(刻画属性) + 方法的定义(刻画行为)
变量的声明部分所声明的变量就是成员变量,也称域变量,它的类型可以是Java中任何一种数据类型,作用域是整个类,与声明位置无关
提倡一行声明一个变量,利于给代码添加注释内容
方法的定义 = 方法声明 + 方法体
方法声明 = 方法的返回类型(任何类型) + 方法名 + ( )参数列表
参数是用逗号隔开的一些变量声明
方法体 = { }以及之间的内容;
方法体中声明的变量和方法的参数被称为局部变量,只在声明它的方法内有效,且与声明位置有关 -
写方法类似于C语言中写函数
-
在局部变量与成员变量同名时,成员变量被隐藏,想用时需要通过
this
显式调用 -
注意:对成员变量的操作只能放在方法中(声明的同时可以赋初值)
-
UML(Unified Modeling Language Diagram) 图属于结构图(统一建模语言图),
常被用于描述一个系统的静态结构
在类的UML图中,第一层是名字层,第二层是变量层,第三层是方法层 -
类是数据类型,可声明变量,类声明的变量被称作对象
声明后必须创建对象(否则对象是空的),
即为对象分配成员变量(为空对象分配"实体"),此时也称给出了这个类的一个实例
如果程序中使用了空的对象,运行时就会出现异常:NullPointerException
由于对象是动态的分配实体,所以Java的 编译器 对空对象不做检查(需要自己注意不要用空对象)
类是一个模板,没有类就没有对象 -
程序用类创建对象时用一种特殊的方法,构造方法
1.构造方法名必须与类名相同 2.构造方法没有类型
默认无参数,允许重载 -
new分配内存后返回的引用 是一个十六进制数,包含地址等
不妨认为引用就是对象在内存里的名字,而且这个名字(引用)是Java系统确保分配给该对象的变量,将由该对象负责 “操作管理”
创建不同对象,返回不同引用 -
调用方法时,局部变量被分配内存空间,方法执行完毕,局部变量即刻释放内存
-
对象中负责存放引用,确保对象可以操作自己的变量和调用类中的方法;
分配给对象的变量习惯地称作对象的实体 -
垃圾回收,(
System.gc()
立即执行垃圾回收)
若检测到某个实体已不再被任何对象所拥有(引用),就释放该实体所占内存
因此Java很少出现"内存泄漏",即由于程序忘记释放内存所导致的内存溢出;
C++中通过析构方法来释放内存 -
参数属于局部变量,方法被调用时,参数变量必须有具体的值
-
Java中,所有参数都是"传值"的,参数的值 是指定值的拷贝,其值更改不影响原变量
可以向double
型参数传递一个float
型的值
引用类型参数,拷贝的是引用,即参数通过引用更改实体,就会导致原变量实体更改(同一个引用,同一个实体);不过更改参数的值(更改引用),对原变量无影响(本就无关) -
Warning:过于冗杂,之后简述
-
可变参数 (The variable arguments),从某项到最后一项类型相同,用
...
表示;
通过 下标 表示具体参数 -
链接:有理数的类封装.
-
对象的组合,一个类可以把对象作为自己的成员变量,用此类创建对象时,该对象将其他对象作为自己的组成部分(即 Has-A)
-
习惯上,将 A关联于B 称作 A依赖于B,在强调A是通过方法参数依赖于B时,在UML图中用虚线连接(可以认为 关联于 包括 依赖于)
实例成员与类成员
-
实例变量与类变量的区别:
1.不同对象的实例变量互不相同
2.所有对象共享类变量
3.通过类名直接访问类变量
(类变量可通过某个对象或类名访问;成员变量可通过对象访问,不可通过类名访问) -
类变量并没有破坏封装性,只是共享
-
实例方法与类方法的区别:
1.对象调用实例方法
2.类名调用类方法(与类变量类似)
(实例方法中可以操作实例变量和类变量,不可通过类名调用;
类方法中只能操作类变量 (因为实例变量刚开始没分配内存),可通过类名或对象调用) -
创建第一个对象时,实例方法被分配入口地址,该入口地址被所有对象共享;
在所有对象都不存在时,该入口地址被取消; -
程序执行;
类的字节码文件被加载到内存;
给类变量分配相应的内存空间,给类方法分配相应的入口地址;
若创建对象,类中实例变量被分配内存空间,实例方法被分配入口地址(入口地址仅分配一次);
程序退出运行,类变量释放所占内存,类方法入口地址被取消; -
方法重载与多态
Java中存在两种多态:重载 (Overload) 和重写 (Override);
重写和继承相关
重载就是同名不同参,方法的返回类型和参数名字没要求 -
this 关键字,指代当前对象
this 可以出现在实例方法中,不可出现在类方法中 (用类名调用类方法时,可能还没有对象);
当this
出现在实例方法中时,代表 正在调用该方法的 当前对象 -
包,解决不同Java源文件中类名重复问题
关键字package
;默认无名包;建议域名倒置作为包名 -
import 语句,可以将不同包中的类引入
java.lang
包是Java语言的核心类库,包含运行Java程序必不可少的系统类,
系统会自动为程序引入java.lang
包中的类,(如 System类、Math类 等)
用*
导入包中所有的类会增加编译的时间,不影响程序运行的性能,
因为程序执行时,只会将真正使用的类的字节码文件加载到内存 -
访问权限
1.私有变量和私有方法,private
在另一个类中,创建对象不能访问,不能通过类名访问(只能在类内访问,应该提供操作数据的get
set
方法)
2.共有变量和方法,public
在另一个类中,创建对象可以访问,可以通过类名访问
3.友好变量和方法,friendly
(默认,不写)
同一包中的类,可以访问;不同包中不可;
子类和父类不在同一包中时,友好的不会被子类继承
4.受保护的成员变量和方法,protected
同一包中的类,可以访问;不同包中不可;可被子类继承;
进一步说明:在另一个类中,要想创建对象访问,这个类必须和声明protected
变量和方法的类在同一个包中(主要是子类创建对象访问时,需追溯到祖先,看创建对象所在的类是否和祖先在同一包中) -
基本类型的类包装
就是将基本类型包装成引用类型,创建对象后调用dataTypeValue()
方法,返回dataType型数据
我们把能创建 “新” 对象的静态方法称为静态工厂方法;
Integer.valueOf()
就是静态工厂方法,它尽可能地返回缓存的实例以节省内存;
创建新对象时,优先选用静态工厂方法而不是new操作符。 -
反编译,
javap
;文档生成器,javadoc
通过组合对象来复用方法也称 “黑盒” 复用 -
链接:【Java】第4章 上机实践与习题.
第5章 子类与继承
-
子类的继承性,编写一个子类时可以声明成员变量和方法,但有一些成员和方法不用声明就相当于声明了一样(
extends
继承) -
父类中的
private
访问权限 的成员变量和方法不会被子类继承 -
子类和父类不在同一包中时,
private
和友好访问权限的不会被子类继承 -
instanceof
运算符,当左边的操作元是右边的类或子类所创建的对象时,返回ture
-
当用子类的构造方法创建一个子类的对象时,父类的成员变量也都分配了内存
(子构方的第一句就是父的对应构方),但只将子类继承的部分作为分配给子类对象的变量
没被继承的也不是垃圾内存,子类继承的方法可以操作这部分未被继承的变量 -
子类声明的成员变量和继承的同名时,会将继承的成员变量隐藏;
子类可以通过重写隐藏已继承的实例方法;可以通过关键字super
使用被隐藏的方法或成员变量
重写,方法的名字、方法的类型、参数个数、参数的类型和父类的方法完全相同(访问权限不可以降低,(若有)static
不可以去掉)
注:如果父类的方法的类型是 “类”(类是面向对象语言中最重要的一种数据类型,类声明的变量称作对象),重写方法的类型可以是 “子类” -
被隐藏的成员变量和方法不再被 子类创建的对象 拥有,将归关键字
super
所有 -
子类不继承父类的构造方法,所以子构方的第一句应是用
super
调用父构方,即super()
,括号中默认无参(注意这个默认调用父类的不带参的构造方法,父类中要有,不然会报错) -
final
修饰的类不能被继承,没有子类;
final
修饰的方法不能被重写,即不能被隐藏;
final
修饰的成员变量或局部变量,就是常量; -
对象的上转型对象,用子类创建一个对象,将其引用放到父类的对象中;
即,实体是子类负责创建的,上转后会“简化”,只保留继承或隐藏的变量和方法(重写的实例方法保留,注:静态方法的重写不保留);
上转后还可以 通过强制 下转; -
继承与多态
不同子类在重写父类实例方法时可能产生不同的行为,这样上转型对象在调用这个实例方法时就可能具有多种形态 -
abstract
类和方法
abstract
类不能实例化;(注:abstract
类也可以没有abstract
方法)
abstract
方法只允许声明,不允许实现; -
面向抽象编程
abstract
类只关心操作,不关心操作具体实现的细节,方法体的内容细节由它的非抽象子类去完成
核心技术:将abstract
类声明对象作为其子类的上转型对象,该上转型对象就可调用子类重写的方法
Pillar类把Geometry对象作为自己的成员,该成员可以调用Geometry的子类重写的getArea()
方法;这样通过面向抽象来设计Pillar类,使得该Pillar类不再依赖具体类; -
开-闭原则 (Open-Closed Principle)
不需修改系统的核心模块;主要精力集中在应对设计中最有可能因需求变化而需要改变的地方;
对abstract
类的修改关闭,对增加abstract
类的子类开放 -
链接:【Java】第5章 上机实践与习题.
第6章 接口与多态
-
另一种重要的数据类型,接口;
Java的接口更加符合人的思维方式 -
关键字
interface
接口的声明,interface 接口名
接口体,常量的声明 (默认public final static
) 和方法的定义 (默认public abstract
) -
关键字
implements
,实现;
一个类可以实现多个接口 -
一个Java源文件就是由类和接口组成的
-
如果父类实现了某个接口,那么子类也就自然实现了该接口
-
接口也可以被子接口继承
-
抽象类可以不重写接口中的所有方法
-
接口只关心操作,并不关心操作的具体实现;
当不希望某些类通过继承使得它们具有一些相同的方法时,就可以考虑让这些类去实现相同的接口而不是把它们声明为同一个类的子类 -
接口回调(和上转型对象类似)
接口声明的变量称为接口变量,其中可以存放实现该接口的类的实例的引用
实际上,当接口变量调用被类实现的接口方法时,就是通知相应的对象调用这个方法 -
需要使用继承才能更好解决的问题用abstract类;
不需要继承,只需若干类给出某些重要的abstract方法的实现细节,用接口; -
面向接口编程
核心思想是使用接口回调 -
链接:【Java】第6章 上机实践与习题.
第7章 数组与枚举
-
数组是相同类型的变量按顺序组成的一种复合数据类型;
数组通过数组名加索引来使用数组的元素;
数组属于引用型变量,数组元素的类型可以是Java的任何一种类型 -
声明数组,
int arr[];
,或int[] arr;
; -
为数组分配元素;在括号内指定数组元素个数
数组变量arr中存放着这些元素的首地址,该地址称作数组的引用
创建二维数组时,可分别指定数组长度;如int a[][] = new int [2][]
;此时这些一维数组还没有分配元素,所以二维数组还不能使用;
还需要再对两个一维数组进行分配如a[0] = new int [6];
a[1] = new int [12];
Java允许使用int
型变量的值指定数组的元素的个数 -
数组元素的使用
索引越界的话,运行时会发生ArrayIndexOutOfBoundsException
异常; -
length的使用
数组名.length
的值就是数组中元素的个数 -
数组的初始化
创建数组后,系统会给数组的每个元素一个默认的值;
可以在声明数组的同时初始化;(相当于声明后创建再赋值) -
对
char
型数组arr
System.out.println(arr)
,输出arr
的全部元素的值
System.out.println("" + arr)
,与字符串做并置运算,才会输出char
型数组的引用 -
遍历
for each
,对于循环变量依次取数组的每一个元素的值
例如:for(char c : arr)
Arrays.toString(a)
,返回固定格式的字符串 (元素值的表示格式) -
arraycopy
方法,复制数组,需要两个数组
copyOf
,自定义新数组长度,返回一个新数组
copyOfRange
,指定范围,返回一个新数组
方法的前面都是public static
修饰,静态方法
静态方法经常用于工具类 -
排序和二分查找
sort
,升序排序;
binarySearch
,二分查找,需要事先已排序的数组 -
枚举,枚举声明和枚举体;
枚举体中的内容是用逗号分割的字符序列,称为枚举类型的常量;
枚举类型声明完毕后,可用 枚举名 声明一个 枚举变量,枚举变量只能取值枚举类型中的常量;
枚举名.values();
,返回一个一维数组 -
链接:【Java】第7章 上机实践与习题.
第8章 内部类与异常类
-
内部类,在一个类中声明另一个类;
内部类中的方法也可以调用外嵌类中的方法;
内部类类体中不可以声明类变量和类方法;
内部类仅供它的外嵌类使用;
Java编译器生成的内部类的字节码文件的名字和通常的类不同,格式为 “外嵌类名$内部类名”; -
匿名类,就是一个子类,去掉了类声明;(匿名类出现时就是在创建匿名对象)
因为无名,所以不可能用匿名类去声明对象,只能直接创建对象;
匿名类一定是内部类;
同样因为没有类名,创建对象时直接使用父类的构造方法;
Java允许直接用接口名和一个类体创建一个匿名对象(此类体认为是实现了该接口的类去掉了类声明后的类体); -
异常类,异常出现在方法调用过程中;
在方法调用过程中抛出异常对象,终止当前方法的继续执行,同时导致程序运行出现异常,并等待处理; -
try-catch 语句,用来处理异常;
将可能出现异常的操作放在try
部分,方法调用发生异常后,try
部分立刻结束执行,转向执行相应的catch
部分;
各个catch
参数中的异常类都是Exception
的某个子类,这些子类之间不能有父子关系,否则保留一个含有父类参数的catch即可;
finally
子语句,即使return
语句执行后,仍然执行;只有执行了程序退出代码(System.exit(0);
),才不执行; -
自定义异常类,扩展
Exception
类定义自己的异常类;
throws
关键字,在方法声明时可以用来声明要产生的若干个异常,
在方法体中具体给出产生异常的操作,即用相应的异常类创建对象,
并用throw
关键字抛出该异常对象,导致该方法结束执行;
注意这是两个关键字 -
断言,在调试代码阶段非常有用;
assert booleanExpression
;
当booleanExpression
的值是false
时,程序从断言处停止执行;
assert booleanExpression : messageException
;
当其值是false
时,程序从断言出停止执行,并输出messageException
表达式的值;
当java
解释器直接运行应用程序时,默认为关闭断言语句; -
链接:【Java】第8章 上机实践与习题.
第9章 常用实用类
-
String 类
Java专门提供了用来处理字符序列的 String 类,在java.lang
包中;
并将其声明为final
类,用户不能扩展;
字符串常量、变量都是对象,可将字符串常量的引用赋值给一个字符串变量;
——————
string.length();
,获取一个字符串的长度;
equals(String s);
,比较当前字符串对象的实体是否与参数s指定的字符串的实体相同;
IgnoreCase
,忽略大小写;
startsWith(String s);
,判断字符串对象前缀是否是s指定的字符串;
endsWith(String s);
,后缀;
compareTo(String s);
,按字典序比较大小;
contains(String s);
,是否包含参数指定字符串;
indexOf(String s);
,返回首次出现的 s 的索引位置;
substring(int start, int end);
,截取子串,前包后不包(Java中很多方法都这样);
trim();
,去掉前后空格,返回一个字符串对象;
——————
java.lang
包中的 Integer 类,
其类方法parseInt(String s);
,将 s 转化为 int 型数据;
相应的包装类中有相应的类方法,不过都有(throws NumberFormatException
);
String 的类方法valueOf(123);
,将基本数据类型转化为字符串;
——————
应用程序中的 main 方法中的参数 args 能接收用户从键盘键入的字符串;
java.lang
包中 Object 类有一个toString()
方法,获得对象的字符串表示,可重写;
——————
getChars();
,字符串一部分复制到足够大的数组;
toCharArray();
,返回一个字符数组;
getBytes();
,转化为字节数组;(使用平台默认字符编码)
getBytes(String charsetName);
,必须在 try-catch 语句中调用;(使用参数指定字符编码)
链接:【Java】字符串的加密算法.
——————
正则表达式,是含有一些具有特殊意义字符(元字符)的字符串;
matches(String regex);
,是否和参数regex
指定的正则表达式匹配;
正则表达式中可以用方括号扩起若干个字符来表示一个元字符;
.
代表任何一个字符,要使用 点 时,必须用[.]
或用\56
表示;
有关正则表达式的细节可查阅java.util.regex
包中的 Pattern 类;
replaceAll(String regex, String replacement);
,所有和regex
指定的正则表达式匹配的子字符串被replacement
指定的字符串替换;该方法返回一个字符串;
split(String regex);
,用regex
作为分隔,返回一个字符串数组;(分解字符串) -
StringBuffer 类 (现在还有一个StringBuilder类),该类能创建可修改的字符串序列,即实体可以发生改变;常用方法:
append(String s);
,追加;
charAt();
,setCharAt(int n, char ch);
,获取,设置;
insert(int index, String str);
,插入;
reverse();
,翻转;
delete(int startIndex, int endIndex);
,删除;
replace(int startIndex, int endIndex, String str);
,替换; -
StringTokenizer,构造字符串分析器,将字符串分解成可被单独使用的单词,默认分隔标记是空格;
分隔标记的任意组合仍然是分隔标记; -
链接:用Scanner解析字符串.
默认使用空格作为分隔标记;
使用正则表达式作为分隔符解析字符串useDelimiter(正则表达式)
; -
Date 类,在
java.util
包中;
构造Date对象
1,使用无参构方,new Date()
,可获取本地当前时间;
2,使用带参构方,Date(long time)
,是距公元(1970.1.1 0时 格林威治时间)的毫秒数;
可用 System 类的静态方法currentTimeMillis()
获取系统当前时间,即从公元到现在的毫秒数;
Date 对象默认表示时间的顺序是:星期、月、日、小时、分、秒、年;
日期格式化,可用java.text
包中的 DateFormat 的子类 SimpleDateFormat
其构方需传入String pattern,例如pattern = "yyyy-MM-dd"
; -
Calender 类,在
java.util
包中;
只能用其静态方法getInstance()
初始化一个日历对象;
可以用set
方法将日历翻到任何一个时间;
用get(int field)
,获取有关年份月份等信息;(注意0表示一月,1表示星期日)
getTimeInMillis();
将时间表示为毫秒; -
Math 和 BigInteger 类;
java.lang
包中的 Math 类包含许多用来进行科学计算的类方法,还有两个静态常量,E 和 PI;
java.math
包中的 BigInteger 类提供任意精度的整数运算,可用来处理大整数; -
DecimalFormat 类,对输出的数字结果进行必要的格式化;
-
Pattern 和 Match 类,专门用来进行模式匹配的,在 java.util.regex 包中;
-
System 类,在
java.lang
包中;
其中有许多类方法,用于设置和 Java 虚拟机相关的数据;
例如:System.exit(int status)
,关闭 Java 虚拟机; -
链接:【Java】第9章 上机实践与习题.
第10章 输入、输出流
-
输入流的指向称作它的源;(读出)
输出流的指向称作它的目的地;(写入) -
File 类的对象主要用来获取文件本身的一些信息,不涉及对文件的读写操作;
File(String filename)
创建文件,当filename
是文件名时,该文件默认为与当前应用程序在同一目录中; -
目录,File 对象调用方法
mkdir()
创建一个目录,若目录已经存在将返回false
;
方法list()
以字符串形式返回文件;
方法listFiles()
用 File 对象形式返回文件;
带参(指定类型)的接收一个实现 FilenameFilter 接口的对象; -
文件的创建与删除
File 对象调用方法createNewFile()
;delete()
; -
运行可执行文件,用
java.lang
包中的 Runtime 类;
用静态方法getRuntime()
创建 Runtime 对象;
然后调用exec(String command)
,打开可执行文件或执行一个操作; -
字节流与字符流,在
java.io
包中,提供了大量的流类;
抽象类 InputStream 和 OutputStream 类的子类创建的流对象,就是字节流;
抽象类 Reader 和 Writer 类的子类创建的流对象,就是字符流; -
InputStream 类提供的
read
方法以字节为单位顺序读取源中的数据,直到源的末尾或输入流被关闭;
Reader 类提供的read
方法以字符为单位;(方法返回实际读取字节数、字符数)
close()
方法关闭流; -
文件字节流,InputStream 专门提供了读写文件的子类 FileInputStream 和 FileOutputStream 类;
前者调用read
方法以字节为单位读取文件;
后者调用write
方法时,若文件不存在,先创建文件;若已存在,则 刷新文件内容,再写入;
FileOutputStream 的构造方法中,若参数append
取值为true
,则输出流不会刷新文件(尾加); -
文件字符流,字节流不能很好地操作 Unicode 字符;FileReader 和 FileWriter 类;
-
注:
write
方法建数据首先写入到缓冲区,每当缓冲区溢出时,缓冲区的内容被自动写入到目的地(一般是磁盘文件);
若关闭流,缓冲区内容立即被写入;flush()方法可用立刻冲洗当前缓冲区,内容写入; -
缓冲流,BufferedReader 和 BufferedWriter 类;
二者的源和目的地必须是字符输入流和字符输出流;
能够读取文本行,readLine()
;
独有的换行符,newLine()
;
可用把 BufferedReader 和 BufferedWriter 称作上层流,把它们指向的字符流称作底层流;
Java采用缓冲技术将上层流和底层流连接;(即底层将数据读入缓存,BufferedReader再从缓存读取数据); -
随机流,不是输入输出流的子类,RandomAccessFile 构方参数
mode
可取r
或rw
;
seek(long a)
,用来定位随机流的读写位置;
对文件的读写比顺序读写更为灵活;
其readLine()
方法在读取含非ASCII字符的文件时(如汉字),会出现乱码;
此时需要重新编码:
①读取,String str = in.readLine();
②重新编码,byte b[] = str.getBytes("iso-8859-1");
③使用当前机器的默认编码将字节数组转化为字符串,String content = new String(b)
; -
数组流,流的源和目标除了可以是文件外,还可以是计算机内存;
字节数组输入流,ByteArrayInputStream;
(不同构方)字节数组输出流,指向一个默认大小为32字节的缓冲区,另一个是设置初始大小size,缓冲区容量会自动增加;
字符数组流,CharArrayReader 和CharArrayWriter 类; -
数据流,允许程序按着机器无关的风格读取Java原始数据,即不必关心这个数值应当是多少个字节;
例:DataInputStream(InputStream in)
,指向一个由参数in指定的底层输入流; -
对象流,ObjectInputStream 和 ObjectOutputStream 类,
ObjectInputStream(InputStream in)
,指向是一个输出流对象;
writeObject(Object obj)
,将一个对象obj写入到一个文件;
readObject()
,读取一个对象到程序中;(根据对象的序列化信息创建一个对象)
使用对象流时,要保证对象是序列化的;
一个类如果实现了 Serializable 接口(在java.io
包中),那么这个类创建的对象就是所谓的序列化的对象;
Java类库提供的绝大多数对象都是所谓序列化的;
Serializable接口中的方法对程序是不可见的,可看成没有方法,所以实现该接口无需实现方法; -
对象克隆,先用对象输出流将对象写入目的地,再用对象输入流将目的地当作源读出;即使用对象输入流通过对象的序列化信息来得到当前对象的一个克隆;(先写入,再读出)
想较快的得到克隆对象,可用对象流将对象的序列化信息写入内存而不是写到磁盘; -
文件锁,不允许多个程序同时处理一个文件;
1.用随机流建立指向文件的流对象,读写属性必须为rw
2.Input 流调用方法getChannel()
获得一个连接底层文件的 FileChannel 对象(信道)
3.信道调用tryLock
或lock
获得一个 FileLock 文件锁,即对文件加锁;
release()
释放文件锁; -
使用Scanner解析文件,相比解析字符串就是多了一个创建文件对象;默认分隔标记仍是空格;
-
使用Console流读取密码;
首先使用 System 类调用console()
方法返回 Console 流;
然后 Console 流调用readPassword()
读取用户在键盘输入的密码,用char[]
返回; -
链接:【Java】第10章 上机实践与习题.
第11章 JDBC操作Derby数据库
-
JDBC (Java DataBase Connectivity)技术,不依赖所选的数据库;
是专门用于操作数据库的API;
JDBC操作不同的数据库仅仅是连接方式上的差异而已;
操作:- 与一个数据库建立连接
- 向已连接的数据库发送SQL语句
- 处理SQL语句返回的结果
-
Java平台提供了一个DBMS,由Apache开发,项目名称为Derby,纯Java实现、开源;
-
Derby数据库相关的类,以jar文件的形式存放在db\lib目录中,需要将其复制到Java运行环境的扩展中,也可以更改系统的环境变量;
-
内置Derby数据库,应用程序和该数据库必须驻留在相同的计算机上;(需要将
derby.jar
复制到扩展) -
ij
环境,该环境下可以使用ij
工具来连接数据库,建表、增删改查等操作;
在指定目录下执行ij.bat批处理文件,启动ij
环境;
exit + 分号
,退出ij环境; -
连接内置derby数据库的
ij
命令
其中数据库是名字,true是数据库不存在时新建数据库,false是数据库不存在时直接放弃;
connect 'jdbc:derby:数据库;create=true|false';
connect 'jdbc:derby:shop;create=true'; //例子
connect 'jdbc:derby:D:/00/boy;create=true'; //指定数据库所在目录
-
连接数据库以后,
ij
命令就是标准的SQL语句; -
网络Derby数据库,允许网络上其他计算机中的java程序通过网络访问该网络Derby数据库;(还需要
derbynet.jar
,derbyclient.jar
)
网络Derby数据库驻留的计算机称为服务器端,服务器端启动Derby数据库服务器,以便用户访问;(用户端、客户端)
startNetworkServer.bat //启动
- 连接网络Derby数据库;
可以另开一个命令行窗口模拟客户端;客户端启动ij环境,然后连接网络Derby数据库;
connect 'jdbc:derby://数据库服务器IP:1527//数据库名;create=true|false';
connect 'jdbc:derby://127.0.0.1:1527//student;create=true'; //例子
-
Derby数据库以文件夹的形式存放,而不是以文件形式存放;
-
连接内置数据库的代码(上面是ij命令):
-
1.加载Derby数据库驱动程序;
try {
Class.forName("org.apache.derby.jdbc.EmbeddedDriver"); //加载驱动
}
catch(Exception e) {
System.out.println("rrrr" + e);
};
- 2.连接内置Derby数据库;
首先用java.sql
包中的 Connection 类声明一个对象,
然后再使用类 DriverManager 调用它的静态方法getConnection
创建这个连接对象,示意代码:
Connection con =
DriverManager.getConnection("jdbc:derby:数据库;create=true|false");
- 连接网络数据库的代码:
try {
Class.forName("org.apache.derby.jdbc.ClientDriver"); //加载驱动
}
catch(Exception e) {
System.out.println("rrrr" + e);
};
Connection con =
DriverManager.getConnection("jdbc:derby://数据库服务器IP:1527//数据库名;create=true|false");
-
查询操作:
-
1.向数据库发送SQL查询语句;
用 Statement 声明一个SQL语句对象,用已创建的连接对象con
调用createStatement()
创建该SQL语句对象;
try {
Statement sql=con.createStatement();
}
catch(SQLException e) {}
- 2.处理查询结果;
SQL对象可以调用相应的方法实现对数据库中表的查询和修改,并将结果放在一个 ResultSet 类声明的对象中;(结果集对象)
ResultSet对象一次只能看到一个数据行,用next()
方法走到下一个数据行;
ResultSet rs = sql.executeQuery("SELECT * FROM goods");
-
无论字段是何种属性,总可以使用
getString
方法返回字段值的串表示; -
顺序查询,利用 ResultSet 类的
next()
方法; -
控制游标,
createStatement(int type, int concurrency);
type
的取值决定滚动方式; -
条件查询,主类将查询条件传递给 Query 类的实例;
query.setSQL(SQL);
query.outQueryResult();
- 更新、添加与删除操作
创建(删除)表:Statement 对象调用int executeUpdate(String sqlStatement)
或boolean execute(String sqlStatement)
sta.executeUpdate(s); //创建表biao
sta.execute("drop table biao"); //删除曾建立的biao表
-
预处理机制,更高效率的数据库操作机制,PreparedStatement,预处理语句对象;
- 当发送一条SQL给数据库时,
数据库中的SQL解释器负责把SQL语句生成底层的内部命令,
然后执行该命令,完成有关的数据操作; - 已创建的连接对象
con
可调用prepareStatement(String sql)
,对sql
指定的SQL语句进行预编译处理,并将生成的命令封装在 PreparedStatement 对象中;
- 当发送一条SQL给数据库时,
-
事务及处理,事务由一组SQL语句组成,处理就是这组语句要么全部执行,要么全不执行;
是保证数据库中数据完整性与一致性的重要机制;
JDBC事务处理步骤:
1.使用setAutoCommit(boolean autoCommit)
方法,关闭默认设置(默认自动提交,SQL语句立刻生效)
2.直到连接对象调用commit()
方法,事务中SQL才会全部生效
3.rollback()
方法,撤销事务中成功执行过的SQL语句对数据库数据所做的更新等操作,将数据库中数据恢复到commit()方法执行之前的状态;(出现SQL语句执行失败时使用) -
批处理,Statement 对象调用
executeBatch()
方法可以一次性执行多个SQL语句; -
CachedRowSetImpl 类,缓冲结果集,其对象可以保存 ResultSet 对象中的数据;
JDBC使用 ResultSet 对象处理SQL语句从数据库表中查询记录,
但是 ResultSet 对象和数据库连接对象(Connection 对象)实现了紧密的绑定,
一旦连接对象被关闭,ResultSet对象中的数据立刻消失;
将 ResultSet 对象rs
中的数据保存到 CachedRowSetImpl 对象rowSet
中的代码:rowSet.populate(rs);
-
链接:【Java】第11章 上机实践与习题.
第12章 泛型与集合框架
-
Java集合框架,是实现数据结构的类的通称;
JDK1.5之后,Java集合框架开始支持泛型; -
泛型 (Generics),可以建立具有类型安全的数据结构;
优点:在使用这些泛型类建立数据结构时,不必进行强制类型转换,即不要求运行时进行类型检查; -
泛型类,如:
class ShowObject<E>
,其中E是泛型;
E只能是类和接口,不能是基本数据类型;
“泛型列表” 给出的泛型可以作为类的成员变量的类型、方法的类型以及局部变量的类型;
泛型类声明和创建对象时,必须要用具体的类型替换<>中泛型; -
泛型类中的泛型变量只能调用 Object 类中的方法;如:
toString()
; -
泛型接口,
interface 名称<泛型列表>
;
泛型类和普通类都可以实现泛型接口,但是普通类实现泛型接口时,必须指定泛型列表中具体类型; -
链表,习惯上称
java.util
包中的 LinkedList 泛型类创建的对象为链表对象;
创建链表时,必须指定 E 的具体类型;
节点是自动链接在一起的;
LinkedList< E > 泛型类实现了泛型接口 List< E >;
List< E > 又是 Collection< E > 泛型接口的子接口;编程时可以使用接口回调技术; -
Java集合框架为各种数据结构的集合都提供了迭代器;
链表对象可以使用iterator()
方法获取一个 Iterator 对象,该对象就是针对当前链表的迭代器;
调用next()
方法获取值; -
动态数组表类 ArrayList,采用顺序结构;
链表,采用链式结构;这是二者的本质区别,别的地方区别不大; -
排序,若 E 实现了 Comparable 接口,如 String 对象,那么就可以用:
Collectioin 类调用sort(List<E> list)
方法对参数指定的列表进行排序;(升序)
一个类可以实现泛型接口 Comparable< E > 中的compareTo(E b)
方法来指定该类实例互相比较大小关系的准则; -
Collection类提供的类方法:
洗牌,shuffle(List<E> list)
,随机排列list
中节点;
旋转,rotate(List<E> list, int distance)
,list
索引为i
的节点中的数据将是调用方法前索引为(i - distance) mod list.size()
的节点中的数据;
反转,reverse(List<E> list)
; -
堆栈,Stack< E > 泛型类,“压栈”、“弹栈”;
使用堆栈可以节省内存的开销;
可以借助堆栈消除大部分递归; -
散列映射,HashMap<K , V> 的对象,用于存储 “键/值” 对;
HashMap<K, V> 泛型类实现了泛型接口 Map<K, V>;
若装载因子为0.75,当散列映射容量使用75%时,它就把容量扩大一倍;
若不知位置,数组表和链表需从头开始访问,此时建议用散列映射存储数据,可以减少检索的开销;
public Collection<V> values()
方法返回一个实现接口的类的对象,对象引用赋给接口变量,可以回调iterator()
方法获取一个存放着散列映射中所有键值对中的值的 Iterator 对象 -
树集,TreeSet< E > 类实现了 Set< E > 接口,采用树结构存储;
在同一层中的节点从左到右按字从小到大递增排列,下一层的都比上一层的小;
不允许出现大小相等的两个节点;
节点的排列不按添加的先后顺序排列;按对象的大小升序排列;
树集中数据若是实现了 Comparable< E > 泛型接口的类的对象,按对象大小关系排列; -
树映射,TreeMap<K, V> 类实现了 Map<K, V> 接口,与树集不同的是节点按照关键字升序排列;
-
自动装箱与拆箱功能 (Autoboxing and Auto-Unboxing of Primitive Types),可以将基本数据类型的数据添加到类似链表的数据结构中了;
第13章 Java多线程机制
-
程序是一段静态的代码,进程是程序的一次动态执行过程;
代码加载、执行、执行完毕;进程产生、发展、消亡; -
线程,比进程更小的执行单位,一个进程执行时可产生多个线程;(小进程)
进程共享操作系统资源;线程间共享进程中某些内存单元;
线程的中断与恢复可以更加节省系统的开销;
没有进程就不会有线程,没有操作系统就不会有进程; -
多线程,指一个应用程序中同时存在几个执行体,按几条不同的执行线索共同工作;
给人多个事件同时发生的错觉;其实是JVM将控制快速地在线程之间切换; -
JVM 加载代码,发现
main
方法之后,启动一个线程,称为主线程;
主线程执行中若创建其他线程,JVM 就会在各线程之间切换 CPU 资源使用权;
所有线程都结束,JVM 结束 Java应用程序; -
Thread 类及其子类的对象表示线程;
-
线程的生命周期:
1.新建,拥有内存空间和其他资源;
2.运行,调用start()
方法通知 JVM 排队等候切换;
重写的run()
方法规定了该线程的具体使命;(run()
方法是自动执行的 )
注:线程未结束时若再次调用start()
将会发生 ILLegalThreadStateException 异常;
3.中断,四种原因:
①JVM 切换,让出 CPU 使用权;
②调用sleep()
方法,让出 CPU 使用权;
③调用wait()
方法,退出等候队列,需其他线程调用notify()
方法通知其再次进入队列等候切换;
④进入阻塞状态,退出队列,阻塞原因消除时,重新入队;
4.死亡,线程释放实体;
两种原因,一是run()
方法所有语句执行完毕,二是强制run()
方法结束; -
线程调度与优先级,Java线程优先级一共10级;
可以通过setPriority(int grade)
方法调整优先级;
Java调度器任务是使高优先级的线程始终运行;
要编写正确、跨平台的多线程代码,必须假设线程在任何时刻都有可能被剥夺CPU资源使用权; -
多继承就是就是多个父类;
-
使用 Runnable 接口,用 Thread 类直接创建对象,构造方法
Thread(Runnable target)
;
比使用 Thread 的子类更具灵活性;回调;
同一个run()
方法可以启动多次,分别运行在不同的线程中,即运行在不同的时间片内; -
run()
方法是系统自动调用而用户程序不得引用的方法;
sleep(int millsecond)
,放弃 CPU 资源,休眠一段时间,休眠时间的长短由sleep方法的参数决定;
若休眠时被打断,JVM 就抛出 InterruptedException 异常;
isAlive()
,新建状态和死亡状态返回false
; -
注意:一个已经运行的线程在没有进入死亡状态时,不要再给线程分配实体;
线程只能引用最后分配的实体,先前的实体就会称为垃圾,并且不会被垃圾收集机制处理掉;
JVM认为先前的实体仍在运行状态; -
currentThread()
返回当前正在使用 CPU 资源的线程; -
interrupt()
常用来“吵醒”休眠的线程,即导致休眠的线程发生 InterruptedException 异常,从而结束休眠,重新排队; -
线程同步,就是若干个线程都需要使用一个
synchronized
修饰的方法;(加锁)
解决 程序的运行结果依赖 JVM 切换线程使用 CPU 的时机 的问题; -
在同步方法中,
wait
方法可以中断方法的执行,暂时让出CPU使用权,并允许其他线程使用这个同步方法;
当其他线程使用完这个同步方法时,应当调用notifyAll()
方法通知所有由于使用这个同步方法而处于等待的线程结束等待,并遵循“先中断先继续”原则;notify()
只通知一个;
链接:wait 方法的注意点. -
线程联合,其他线程调用
join()
方法插队,本线程中断;
第14章 Java网络编程
- URL 类,在
java
包中;
其实例封装着一个统一资源定位符 (Uniform Resource Locator);
使用 URL 创建对象的应用程序称作客户端程序;
URL 对象,包含最基本的3部分信息:协议、地址、资源;
构造方法:
public URL(String spec) throws MalformedURLException;
//如:spec = "http://www.google"
public URL(String protocol, String host, String file) throws MalformedURLException;
//参数对应,协议、地址、资源
-
读取 URL 中的资源;
URL 对象调用InputStream openStream()
方法返回一个输入流,指向资源;
可通过输入流将服务器上的资源信息读取到客户端; -
Internet 上的主机的两种表示地址的方式:
1.域名,如 www.tsinghua.edu
2.IP地址,如 202.108.35.210
域名容易记忆,在连接网络时输入一个主机的域名后,
域名服务器 (DNS) 负责将域名转化为 IP 地址,这样才能和主机建立连接; -
InetAddress 类,在
java
包中,其对象包含域名和 IP 地址;
其类方法:getByName(String s)
获取主机地址,传域名或 IP 给参数s
;
实例方法:getHostName()
获取域名,getHostAddress()
获取 IP 地址; -
网络通信使用 IP 地址标识一个计算机,使用端口号标识服务器上的进程 (程序);
若服务器上的一个程序不占用一个端口号,用户程序就无法找到它;
端口号,被规定为一个16位的0 ~ 65535的整数,其中0 ~ 1023是被特定服务占用; -
套接字,端口号与 IP 地址的组合得出一个网络套接字;
当两个程序需要通信时,它们可以通过使用 Socket 类建立套接字对象并连接在一起; -
客户端套接字,构造方法
Socket(String host, int port)
,其中host
是服务器的 IP 地址,port
是一个端口号;可能发生 IOException 异常;
建好套接字对象mysocket
后,可以调用方法getInputStream()
方法返回一个输入流,该输入流的源恰好是服务器端的一个输出流的目的地;
mysocket
调用getOutputStream()
方法返回一个输出流,其目的地恰好是服务器端一个输入流的源;
借此通信; -
ServerSocket 对象与服务器端套接字;
客户负责呼叫,服务器建立 ServerSocket 对象,可以将服务器的套接字对象与客户端的套接字对象进行连接;
ServerSocket(int port)
,port
是客户呼叫的端口号;该端口若被占用,抛出 IOException 异常;
建立对象serverForClient
调用accept()
方法连接两个套接字:
Socket sc = serverForClient.accept();
返回一个与客户端套接字连接的套接字sc,驻留在服务器端,调用getInputStream()
getOutputStream()
方法与客户端通信;
accept()
会堵塞线程,直到接收到客户的呼叫;
连接后,套接字对象调用getInetAddress()
方法获取对方的IP地址和域名;
通信完毕,close()
方法关闭套接字连接; -
使用多线程技术;
使用套接字连接时,在另一端数据发送出来之前,这端就可能开始试着读取了,会堵塞线程;
服务端收到一个客户的套接字后,用多线程技术启动一个专门为该客户服务的线程;
Socket()
构方创建一个套接字对象,调用connect(SocketAddress endpoint)
方法连接参数指定的服务器端的套接字;
需用 SocketAddress 的子类 InetSocketAddress(InetAddress addr, int port)
创建一个对象; -
套接字时基于 TCP 的网络通信
-
基于 UDP (用户数据报协议) 的信息传递更快,但不提供可靠性保证;
基本模式:将数据打包,称为数据包,发往目的地;
接收别人发的数据包,查看数据包内容; -
发送数据包;
用 DatagramPacket 类将数据打包;
DatagramPacket (byte data[], int length, InetAddress address, int port)
;
address
是目标地址,port
是目标端口;
用 DatagramSocket 类无参构方创建对象负责发送数据包; -
接收数据包;
用DatagramSocket(int port)
创建一个端口号匹配的对象,调用receive(DatagramPacket pack)
方法接收数据包;(该方法可能堵塞,直到收到数据包)
此时需要用DatagramPack(byte data[], int length)
构造另外一个数据包来接收数据包;(数据包长度不要超过8192KB) -
广播数据报
Internet 的地址形式 a.b.c.d;其中一部分表示主机,另一部分表示用户所在的网络;
A类地址,a < 128,b.c.d用来表示主机;
B类地址,128 <= a <192,a.b表示网络地址,c.d表示主机地址;
C类地址,192 <= a,a.b.c表示网络地址,d表示主机地址;
D类地址,224.0.0.0 ~ 224.255.255.255,保留地址;
要广播或接收广播的主机都必须加入到同一个D类地址,一个D类地址也被称作一个组播地址; -
Java远程调用 (Remote Method Invocation , RMI),一种分布式技术;
习惯上,称发出调用请求的虚拟机为(本地)客户机,称接收并执行请求的虚拟机为(远程)服务器; -
远程对象及其代理
远程对象,驻留在(远程)服务器上的对象;
客户程序请求远程对象调用方法,然后远程对象调用方法并返回必要的结果;
代理与存根 (Stub);
代理与远程对象实现了相同的接口,向用户公开了相同的方法;
存根,一种特殊的字节码,存根产生的对象作为远程对象的代理;
代理需要驻留在客户端;
远程对象必须实现 Remote 接口,在java.rmi
包中,接口中没有方法,仅仅起到一个标识作用; -
RMI 的设计细节
- 1.扩展 Remote 接口,就是定义一个子接口;
该接口保存在远程服务器目录中,并编译生成.class
字节码文件;
客户端远程代理也需要该接口,因此需复制到客户机的目录中;
在实际项目设计中,可以提供 Web 服务让用户下载该接口的.class
文件; - 2.远程对象,让一个对象成为远程对象,
要实现 Remote 接口的一个子接口;
使其类是java.rmi.server
包中的 UnicastRemoteObject 类的子类; - 3.存根 (Stub) 与代理,RMI 使用
rmic
命令产生存根 (Stub Object);
若创建远程对象的字节码是 RemoteConcreteSubject.class,
那么存根的字节码就是加了后缀_Stub
的 RemoteConcreteSubject_Stub.class; - 4.启动注册:
rmiregistry
;后台启动代码start rmiregistry
;
先启动,远程服务器才能创建远程对象,并将对象注册到rmiregistry
所管理的注册表中; - 5.启动远程对象服务,编写程序创建和注册远程对象,并运行该程序;
远程服务器调用java.rmi
包中的 Naming 类的类方法:rebind(String name, Remote obj)
,
绑定远程对象到注册表中;name
参数是 URL 格式;将来代理通过name
找到obj
; - 6.运行客户端程序,客户端调用 Naming 类的类方法
lookup(String name)
,返回一个远程对象的代理;name
取值为远程对象注册的name
;
- 1.扩展 Remote 接口,就是定义一个子接口;
第15章 Java图形用户界面设计 (无)
End.
更多推荐
【Java】Java程序设计食用教程
发布评论