一、JDK(Java 开发工具集)1.8 安装与配置
1、安装JDK,注意OS系统的位数 32|64
2、配置环境变量
用户变量:只用于当前用户
系统变量:用于所有用户
path、classpath,注意:不区分大小写
path:C:\Program Files\Java\jdk1.8.0_101\bin 一系列可执行文件目录,比如:java.exe
classpath:.;C:\Program Files\Java\jdk1.8.0_101\lib\tools.jar 一系列核心类库
3、安装好JDK, 安装目录下有俩个文件:jdk与jre
jdk:开发环境+运行环境
存在 javac.exe可执行文件
存在 java.exe
jdk中存在jre
jre:运行环境
不存在 javac.exe可执行文件
存在 Java.exe
Java是一种编译性语言:
先编译:javac .java,属于开发过程;编译后生成.class(字节码)文件
后执行:java ,属于程序执行过程
注意:是类名
4、常用命令:
javac:编译Java源文件,生成字节码文件
-d 指定Java源文件所在位置
D:\java_demo\temp> javac -d . D:\java_demo\20160726\HelloWorld.java
查找其他目录下的Java源文件,编译生成字节码文件存放当前目录。
指定Java源文件编译后的class字节码文件的存放目录
D:\java_demo\20160726> javac -d D:\java_demo\class HelloWorld.java
当前目录下编译Java源文件,将生成的字节码文件存放指定其他目录下。
-cp 指定查找用户类文件的位置
D:\java_demo\20160726> java -cp D:\java_demo\temp HelloWord
查找其他目录下的字节码文件,解释执行该文件。
java:执行字节码(.class)文件,展示运行效果
javadoc:生成帮助API文档
javadoc ***.java .java ...
生成目录下所有的类的帮助文档
cd 打开指定目录,执行命令: javadoc *
jar:打包多个类,生成一个类库.jar
jar cvf ***.jar 目录名(文件所在目录)
二、JRE(Java 运行环境)
1、 主要三项功能:
加载代码
校验代码
执行代码
2、类的执行过程
前提:类已经被编译
1)加载类:加载器加载类的字节码文件
2)校验类:字节码校验器,校验类是否存在非法代码
3)执行类:解释器解释执行
扩展:编译性语言与解释性语言
编译性语言:先编译后执行
C++、Java、C#
解释性语言:不需要编译直接执行
HTML、JavaScript、PHP
三、创建Java类
注意:命名规范——类名首字母大写,若由多个单词组成,多个单词首字母均大写。
若要创建的Java类可直接执行:
1)类名与Java文件名相同;
2)存在程序入口方法 public static void main(String[] args){......}。
注释:
// 单行注释
/* / 多行注释
/* */ 文档注释、多行,javadoc 生成API(Application Interface 应用程序接口)帮助文档,给注释会写到帮助文档中
扩展:Java程序的分类
Java Application Java应用程序
Java Applet Java小应用程序,制作网页中的小插件(比如:动画),已过时
四、数据类型
1、基本数据类型
数值型:
整型:byte short int long64位
浮点型:float32位 double 64位
字符型:char,2字节 可以存储一个中文汉字
布尔型:boolean
2、引用数据类型
数组
类
接口
3、数值的表示方式
二进制 0b
八进制 0
十进制
十六进制 0x | 0X
4、数值后标识
长整型 l|L
单精度 f|F
双精度 d|D
5、基本数据类型的初始值
char nul|0|\u0000
boolean false
整型 0
浮点型 0.0
引用数据类型的初始值
null
空字符(nul): 0|\0|\00|\u0000
一、String类型
是引用类型中“类”类型
String表示一串字符,称为字符串;注意多个字符由一个“”括起来。
转义字符
\ + 字符
常用转义字符
\n
\t
\
"
\d
\f
\0
二、数据类型转换
前提:数据类型之间兼容;boolean不能与数值型、char进行类型转换
1、自动数据类转换(隐式数据类型转换)
目的数的类型范围>源数的类型范围,即转换后数类型的范围>转换前的(小向大转换)
float f = 10L; //long型 转换成 float型
byte > short > int > long > float > double
char >
变量间转换:byte或short 与 char不能进行自动类型转换
常量值转换给变量:byte或short 与 char 可以进行自动类型转换,注意:不能超出目的类型的取值范围
2、强制数据类型转换(显示数据类型转换)
类型 变量名 = (类型)变量名|值
int i = 100.25; //double型 转换成 int型
三、变量
可改变的量,用于数值可改变的数据;
1、定义的语法规则:
类型 变量名; //声明变量;内存中没有存储空间
类型 变量名 = 值; //定义变量;内存中有存储空间
2、类型的分类
按数据类型划分:
基本数据类型变量
整型变量
字节型变量
短整型变量
整型变量
长整型变量
浮点型变量
float型变量
double型变量
字符型变量
布尔型变量
引用数据类型变量
类型变量 Person类 Person p; Person变量
接口型变量
数组型变量
按变量所在位置划分:
成员变量——类中方法外或语句块外定义的变量
全局变量——类中方法外或语句块外定义的变量 + static修饰符
局部变量�——方法或语句块中定义的变量
作用域:
成员变量——作用于整个类
局部变量——作用于一个方法或一个语句块
注意:先定义,后使用
三、运算符
算术运算符
+ - * /
% 求余数 3%2 = 1
++ 自增 变量的值+1
前自增 ++i i是一个变量 先自增,再参与运算
后自增 i++ 先参与运算,再自增
-- 自减 变量的值-1
前自减 --i 先自减,再参与运算
后自减 i-- 先参与运算,再自减
关系运算符
> < >= <= == !=
逻辑运算符
true 真 成立
false 假 不成立
! 非 !true false 取反
&& 条件与(逻辑与) true&&false false 两边均为真时,才为真
|| 条件或(逻辑或) true||false true 两边均为假时,才为假
& 与(按位与) true&&false false 两边均为真时,才为真
| 或(按位或) true||false true 两边均为假时,才为假
^(cart)异或 true^true false 两边不同时,结果为真
&&、|| 与 &、|的区别?
&&、||是简洁运算(短路运算),若运算符左边可以确定结果,右边的表达式不参与运算
3!=3&&3>2 false 只计算左边的结果
3>1&&3<4 true 两边均计算
&、|是非简洁运算,不管运算符左边是否可以确定结果,右边均会参与运算
~ &、|、^是位运算符
<< 左移位
>> 右移位
>>> 无符号右移位
赋值运算符
= += -= *= /= %=
+= 变量 += 表达式 --》 变量 = 变量 + (表达式)
字符串连接符
+ 用于连接两个字符串
条件运算符
? : 变量 = 布尔表达式 ? 表达式1 : 表达式2
布尔表达式结果为true,表达1计算;false,表达式2计算。
运算符优先级:
!(逻辑非)、~(按位取反) > 算术运算符 > 关系运算符 > 逻辑运算符 > 赋值运算符
按运算符操作数的数量进行分类:
单目运算符:! ++ -- ~ +(正) -(负)
双目运算符:
三目运算符:? :
四、表达式
由操作数与运算符组成的算术
3+2*5%4 操作数:3 2 5 4
最简单表达式 3 true 'a' i j
一个常量或变量
五、流程控制
1、顺序语句
至上而下,从第一行到最后一行代码一次执行。
2、分支语句
根据一定的条件有选择地执行或跳过特定的语句
if分支语句
if(布尔表达式) {
}
if(布尔表达式) {
} else {
}
if(布尔表达式) {
} else if(布尔表达式) {
} else if(布尔表达式) {
} ......
else {
}
switch分支语句
switch(表达式) {
case 常量:
......
break;
......
default:
......
}
注意表达式的类型:int(char、byte、short)、枚举型(enum)
String(jdk1.7+ 才支持)
case的语句块中加上break; 否则匹配到语句块,其后case均会执行以及default,直到遇到break或整个switch
语句块执行结束。
default:不一定在最后,可以在任何位置。
3、循环语句
4、跳转语句
一、循环语句
在条件满足的情况下,反复执行一段特定的代码。
循环语句的分类
while
while(布尔表达式) {
循环体
}
do..while
do {
循环体
} while(布尔表达式);
while与do..while的区别?
while —— 先判断,后执行循环体;
do..while —— 先执行循环体,再判断;do..while确保至少循环一次,不管条件是否满足。
for
for(初值; 布尔表达式; 迭代值) {
循环体
}
for循环的执行顺序:
1) 初值,初始化语句;
2)布尔表达式,循环条件判断;
3)循环体,执行循环体
4)迭代值,修改“循环条件”中用于条件判断变量的值,一般是++ --。
5)回到 2)位置继续执行
for each 用户遍历数组或集合
for(类型 变量: 数组|集合变量) {
循环体
}
二、跳转语句
break语句:结束当前整个循环
continue语句:结束当前本次循环
结合“语句块标记”、跳转语句结束外层循环
标记一个循环:
标识符:for( ; ; ) {
}
三、数组
数组是多个相同类型数据的有序组合。
数组元素类型是相同的
元素:指定的是数组这个组合中的一个数据,这个数据称为数组元素
数组是有序的
不是元素值(数据的值)有序,元素的位置有序,这个位置称为下标
可以定义任何类型的数组,可以定义基本数据类型数组,可以定义引用类型数组。
数组定义的语法格式:
类型[] 数组名 = new 类型[数组长度] 数组长度——元素个数
数组声明正确的语法格式:
int[] arr;
int [] arr;
int []arr;
int[]arr;
int arr[];
使用new创建数据
new 类型[长度];
int[] arr = new int[]; //错误,为指定长度
int[] arr = new int[5]; //正确
数组的初始化
静态初始化
类型[] 数组名 = {值1,值2, ...., 值n}
动态初始化
类型[] 数组名 = new 类型[数组长度];
注意:每个元素均有相同默认值。
数组名[下标] = 值; //下标从0开始 到 长度-1
提取数组中元素
数组名[下标];//获取数组中指定下标的元素
OOP:面向对象编程
POP:面向过程编程
一、类与对象
类:
抽象的、概念上的;是对一类事物的描述。
描述的是多个同类型的对象。
对象:
实际存在的,存在于计算机的内存中(堆中);是实际存在的一类事物的单个个体。
类是对象抽象化,对象是类的实例化。
抽象化:类将一类对象的特征与行为以文字描述。
实例化:根据类创建一个对象。
类包含属性和方法、对象包含特征和行为。
二、类的成员
属性:
成员变量:
类变量(全局变量):使用static修饰的成员变量,就是类变量;类的所有对象共享。
实例变量:没有使用static修饰的成员变量,就是实例变量;对象间是独立的。
语法格式:
[权限修饰符] [修饰符] 类型 变量名 [= 值];
方法:
构造方法:
成员方法:
类方法:使用static修饰的成员方法;可以使用类名.方法名(参数);
实例方法:没有使用static修饰的成员方法;
语法格式:
[权限修饰符] [修饰符] 返回值类型 方法名([参数列表]) {
方法体
}
方法中的变量(局部变量)特性:
只有final修饰符;final修饰变量为最终变量,只能为其赋一次值,第二次赋值时报错。
使用前必须初始化。
抽象方法:抽象类才有;
语句块
静态块:静态语句块
三、对象的创建
类名 对象名 = new 构造方法([实参列表]);
访问对象属性:
对象名.属性;
访问对象方法:
对象名.方法名([实参列表])
形式参数(形参):方法声明中的参数;
实际参数(实参):方法调用时,有实际值得参数,参数的实际值传递给形参。
四、方法递归
方法自身调用
确定结束递归的条件,否则将发生“堆栈溢出”异常。
OOP:面向对象编程
POP:面向过程编程
一、类与对象
类:
抽象的、概念上的;是对一类事物的描述。
描述的是多个同类型的对象。
对象:
实际存在的,存在于计算机的内存中(堆中);是实际存在的一类事物的单个个体。
类是对象抽象化,对象是类的实例化。
抽象化:类将一类对象的特征与行为以文字描述。
实例化:根据类创建一个对象。
类包含属性和方法、对象包含特征和行为。
二、类的成员
属性:
成员变量:
类变量(全局变量):使用static修饰的成员变量,就是类变量;类的所有对象共享。
实例变量:没有使用static修饰的成员变量,就是实例变量;对象间是独立的。
语法格式:
[权限修饰符] [修饰符] 类型 变量名 [= 值];
方法:
构造方法:
成员方法:
类方法:使用static修饰的成员方法;可以使用类名.方法名(参数);
实例方法:没有使用static修饰的成员方法;
语法格式:
[权限修饰符] [修饰符] 返回值类型 方法名([参数列表]) {
方法体
}
方法中的变量(局部变量)特性:
只有final修饰符;final修饰变量为最终变量,只能为其赋一次值,第二次赋值时报错。
使用前必须初始化。
抽象方法:抽象类才有;
语句块
静态块:静态语句块
三、对象的创建
类名 对象名 = new 构造方法([实参列表]);
访问对象属性:
对象名.属性;
访问对象方法:
对象名.方法名([实参列表])
形式参数(形参):方法声明中的参数;
实际参数(实参):方法调用时,有实际值得参数,参数的实际值传递给形参。
四、方法递归
方法自身调用
确定结束递归的条件,否则将发生“堆栈溢出”异常。
类与类之间的关系:
is a 继承关系
has a 关联关系
use a 依赖关系
A类 B类
A is a B A类是一个B类,即A类继承B类
class A extends b {} B b = new A();
A has a B A类拥有B类,即A类关联B类
class A {
private B b; //关联关系
}
A use a B A类使用B类,即A类依赖B类
class A {
public void method() {
B b = new B();
b.method(); //依赖关系
}
}
一、面向对象的三大特性
1、封装性
1)信息隐藏
为什么使用信息隐藏?
用者对类内部定义的数据(对象的成员变量)的直接操作会导致数据的错误、混乱或安全性问题。
什么是信息隐藏?
类的使用者访问类,不能访问类中某个部分,就可以说,该部分对使用者信息隐藏;
类的定义者,定义类时规定类中某些部分不能被使用者访问,这些部分被信息隐藏。
3) 封装
使用封装对信息进行隐藏
Java中通过将数据(属性)声明为私有的(private),再提供一个或多个公开的(public)方法实现对该属性的操作
private int age;
public void setAge(int age) {
}
public int getAge() {
}
封装的作用:
隐藏一个类的实现细节;
使用者只能通过事先定制好的方法来访问数据,可以方便地加入控制逻辑,限制对属性的不合理操作;
便于修改,增强代码的可维护性。
2、继承性
子类可以继承父类中的全部或部分属性与方法,但不能继承构造方法。
子类继承父类,子类不需要再定义与父类相同的属性与方法,而是直接使用该属性和方法。
父类称为超类或基类,子类也称为派生类
语法格式
[权限] [修饰符] class 类名 extends 父类名 {
}
类只支持单一继承,即extends后只能有一个父类名;不支持多重继承
子类只有一个父类
父类可以派生出多个子类
继承的实现手段:
派生 —— 创建子类
扩展 —— 子类中添加新属性与新的方法
继承作用:
1、代码的重用;
2、定义共同的协议(方法)。
协议访问一个类的接口(访问类的入口),这个接口就是类的方法。
父类引用访问子类对象的方法,该方法重写父类的方法
3、多态性
在程序中同一符号或名字在不同情况下具有不同的语义解释。
一个事物在不同的时候,具有不同的状态。
编译时多态性: 在程序编译时可确定的多态性,由重载机制实现;
运行时多态性: 指程序动态运行时才可确定的多态性,由继承结合动态绑定实现,即由重写机制来实现。
继承 + 动态绑定
A类,B类 extends A类,C类 extends A类
某个方法中
A a = new B();
a = new C();
上面两句代码即动态绑定。A a = new B(); B类的对象绑定给A类引用,注意:B与A存在继承关系。
这种给一个引用变量动态绑定多个不同类型对象,即为运行时多态。
为什么说重写是运行时多态?
运行时多态(不同性)由重写来实现;
子类对象赋值给父类的引用变量,父类引用不能方法到子类扩展属性和方法、以及被重写属性;只能
访问自己的属性和方法,这样就没有所谓的多态。但是父类引用可以通过“共同协议”访问到子类对
象的重写方法(重写父类中方法)。
共同协议:父类提供方法让多个子类重写,该方法即为共同协议。
1)重写
变量重写:子类中存在与父类相同名称的变量;
方法重写:子类中存在与父类相同声明的方法。
1)返回值相同、方法名相同、参数列表相同;
2)访问权限范围>=父类;
3)子类抛出的异常是父类抛出的异常的子类或本类。
作用:子类重写父类变量或方法,子类访问时所访问的是子类的变量与方法,父类中相应变量与方法被隐藏。
2)重载
一个类中定义多个方法名相同、参数列表不相同的方法,就是方法的重载。
目的:同类中共享方法名。
区分方法是否发生重载:
唯一判断方式——参数列表不相同
参数个数不同;
参数类型不相同。
注意:是否发生重载与返回值类型无关。
为什么重载是一种多态性?
同一个方法名,访问到多个不同的方法;
编译时就已经确定了要访问的方法。
比如:编译未匹配到方法,将编译失败。
因此重载的多态性,体现在编译时。
重载的多个方法的参数,存在继承(is a)关系:
访问方法参数为实际类型(对象的类型),匹配参数为实际类型(对象类型)的方法;
访问方法参数是子类类型,重载方法参数只有父类,匹配参数为父类的方法,就近原则。
访问方法参数为形式类型(父类类型指向一个子类类型的对象),匹配参数为形式类型的方法。
在父子关系的重载中,按照引用类型去找。
如:
public fun(One one){}
public fun(Two two){}
One one =new Two();
fun(one);//执行第一个fun(One one)方法
3)运行时多态
一个引用类型变量可以指向多种实际类型对象,这种现象称为多态;即形式类型与实际类型就是多态。
对象在运行时才会创建
这种情况在运行时才能确定,所以是运行时多态。
Animal animal;
animal = new Dog();
animal = new Cat();
通过声明为父类型的对象引用来引用他的子类型对象
。
在继承的关系中体现多态:一个对象变量的引用可以指向多种实际类型的对象。(实际类型和形式类型不同);
父类引用可以指向多个子类。
当一个父类的引用指向一个子类的实例时,子类自有的属性或者方法不可见(自有属性:包括和父类同名的变量);
而同名方法,因为有重写,所以对于重写的方法来说,可以调用;
但同名而不是重写(如:重载),则不能调用
。
二、实例变量与局部变量
实例变量:类中方法外定义的变量,且没有使用static修饰。
局部变量:方法中定义的变量。
局部变量使用前,需要先赋初值。
变量之间的比较
== —— 基本数据类型与引用数据类型用“==”比较
equals —— 常用于比较字符串
三、对象转型
对象转型分为上转型与下转型,属于运行时多态。
上转型(上溯转型)—— 子类引用类型上溯转型成父类引用类型
自动类型转换
父类类型 变量名 = new 子类构造方法(参数列表);
或
子类类型 子类变量名 = new 子类构造方法(参数列表);
父类类型 变量名 = 子类变量名;
下转型(下溯转型、造型)—— 父类引用类型下溯转型成子类引用类型
强制类型转换
子类类型 变量名 = (子类类型) 父类变量;
引用类型间转换,遵守规则:
1)类型间兼容:存在继承关系;
2)下转型时,不能直接将父类对象转型成子类引用类型;需要:
先将子类转型成父类,才可以将父类转型回子类,即,先上后下(下转型前,必须先经过上转型)。
关键字:instanceOf
语言格式:
引用变量名 instanceof 类名;//返回值true|false
用于检查一个对象是否是某个类的实例。
注意:父类、间接父类检查的结果也为true。
四、Object类
Object类是所有Java类的根父类,任何一个Java类直接或间接继承Object类。
如果在类的声明中未使用extends关键字指明其父类,则默认父类为Object类。
五、构造器
类中的构造方法(构造函数)。
构造方法用于创建、初始化对象
对象的创建:new 构造方法名();
语法格式:
[访问权限] 类名(参数列表) {
语句块; //一般做初始化操作
}
特点:
1)没有返回值类型;
2)方法名与类名相同;
3)构造方法可以重载;
4)任何类都有构造方法,若没有显示定义构造方法,类默认存在一个公共的无参的构造方法;
若显示定义构造方法,默认构造方法不再存在,被替代。
思考:
继承关系(is a),创建子类对象时,子类与父类的构造方法的执行情况如何?
A、只有子类构造方法执行
B、先父类构造方法执行,再子类构造方法执行
C、先子类构造方法执行,再父类构造方法执行
答案:B
默认情况下:先执行父类无参构造方法,再执行子类构造方法。
六、关键字:this、super
this:
指向当前对象,相当于当前对象的引用。所有引用就是对象变量,指向一个对象。
this关键字用于构造方法、实例方法;类方法不能使用。
this.成员变量 —— 访问当前对象的实例变量、类变量
this.成员方法 —— 访问当前对象的实例方法、类方法
this(参数列表) —— 访问其他构造方法,只能是构造方法中的第一行代码
super:
指向对象的父类
super关键字用于构造方法、实例方法;类方法不能使用。
super.成员变量 —— 访问父类的实例变量、类变量
super.成员方法 —— 访问父类的实例方法、类方法
super(参数列表) —— 访问父类构造方法,只能是构造方法中的第一行代码
七、实例变量、类变量,实例方法、类方法
1、实例变量与类变量的:
1)定义:
类变量使用static修饰符修饰;
实例变量没有使用static修饰符修饰。
2)不同类访问:
访问类变量,类名.类变量名、对象名.类变量名;
访问实例变量,对象名.实例变量名。
3)数据共享:
类变量,又称静态变量,数据是多个对象共享的;
实例变量,对象之间相对独立的,即非共享的。
2、实例方法与类放方法的区别:
1)定义:
类方法使用static修饰符修饰;
实例方法没有使用static修饰符修饰。
2)不同类访问:
访问类方法,类名.类方法(参数列表)、对象名.类方法(参数列表);
访问实例方法,对象名.实例方法(参数列表)。
3) 同类中访问:
类方法中,只能直接访问类变量、类方法;
若一定要访问实例变量、实例方法,可以使用对象名.实例变量、对象名.实例方法(参数列表)形式方法。
实例方法中,可以直接访问类变量、类方法、实例变量、实例方法。
一、类之间的关联关系
关联关系分类:
A has a B A类关联B类
A: 关联类
B: 被关联类
组合:
关联类的对象与被关联类的对象生命周期相同;
同时创建且同时销毁。
聚合:
关联类的对象与被关联类的对象生命周期相同;
A对象先于B对象创建
B对象先于A对象创建
A对象先于B对象销毁
B对象先于A对象销毁
组合的关联性强度 > 聚合
二、抽象类
用abstract修饰符修饰的类就是抽象类,抽象类不能被实例化。
1、抽象方法:使用abstract修饰符修饰的方法就是抽象方法
1)抽象方法只有方法的声明,没有方法体;
2)抽象类的子类,需要重写父类抽象方法,否则子类仍是抽象类。
2、抽象类的成员
成员变量:
类变量
实例变量
静态块
语句块
构造方法
成员方法:
类方法
实例方法
抽象方法
3、抽象类中不一定存在抽象方法,存在抽象方法的类一定是抽象类。
4、abstract修饰符不能与private、final、static修饰符共用。
修饰方法
private:子类没有访问方法的权限,没有访问权限就不能重写;
final:最终方法,不能被子类重写;
private、final与abstract冲突。
static:static修饰得方法(类方法),子类重写父类类方法,形式上重写,实际上没有重写;
子类对象赋值父类引用,父类引用访问类方法时,访问的是父类的类方法。
@Override验证是否重写,不通过。
三、接口
接口是抽象方法和常量值的定义的集合。
1、接口中的成员
常量
抽象方法
//jdk 1.8+
静态方法 static修饰
接口名.方法名(参数列表); //访问接口的静态方法
默认方法 default修饰
实现类继承接口的默认方法
2、接口的特性
1、接口支持多重继承;
2、接口是一种特殊的抽象类,定义接口时不用abstract修饰符,也可以用abstract修饰;
3、接口默认是(只能是) public abstract,对所有包可见,不能被实例化;
4、接口的变量默认是(只能是)public static final,对所有包中的类可见,共享的,最终的,将其视为“常量”。
5、接口的方法默认是(只能是) public abstract,没有方法体,不能使用private、protected、final、static
native、synchronized修饰符
3、实现接口 implements
语法格式:
[修饰符] class 类名 [extends 父类] implements 接口名1[,接口名2][,接口名...][,接口名N] {
类体
}
一个类可以同时实现多个接口。
4、接口可以继承接口,甚至可以同时继承多个接口
语法格式:
[修饰符] interface 接口名 extends 父接口名1[,父接口名2][,父接口名...][,父接口名N] {
接口体
}
接口支持多重继承。
四、序列化 Serializable
1、Serializable是一个接口,并非关键字;
2、Serializable接口比较特殊又被称做marker,因为它没有任何方法要被实现;
3、
它的作用:在于实现它的类可以被序列化。
序列化的作用:
1)使对象可以在网络上传输;
2)
可以使对象写到文件中。
注意:对象若要在网络上传输或持久化到文件中,该必须是可序列化Serializable接口。
一般要序列化的对象都是VO(Value Object)值对象,成员:实例变量、构造方法、Setter+Getter方法。
五、内部类
一个类内部定义的类,称为内部类。
1、内部类与外层封装它的类之间存在逻辑的所属关系。
编译后内部类会单独生产一个字节码文件(外层类名$内部类名.class);
物理上,外层类与内部类不在一个字节码文件中。
2、内部类一般用在定义它的类或语句块之内。
3、内部类的类名不能包含它的外层类名相同。
4、内部类可以使用包含它的类的静态和实例成员变量,也可以使用它所在方法的局部变量;
内部类能够访问创建它 的对象的实现,包括私有成员;
内部类能够隐藏起来(private),不为其他类所见。
5、内部类的分类:
1)普通内部类
2)方法本地内部类
3)静态内部类
4)匿名类
没有名字的类,当类只会创建一个对象,以后不再用到这个类,就考虑使用匿名类。
思考:
1、抽象类与接口的区别:
抽象类 接口
继承:
只支持单一继承 支持多重继承
定义:
abstract class 类名 { } interface 接口名{ } 默认是public abstract
使用:
子类名 extends 抽象类名 { } 实现类名 implements 接口名1[,接口名2...][,接口N]
内部成员:
普通类的成员:成员变量、成员方法..., 常量、抽象方法
抽象方法 jdk1.8+ 版本中,静态方法、默认方法
特性:
抽象类中方法可以是public、protected、 只有public访问权限
default访问权限
定义抽象类使用abstract修饰符 接口省略了abstract修饰符
一、字符串String类
字符串指的是字符序列
Java中并没有内置的字符串类型(没有基本类型),而是在标准Java库中包含一个String类。
字符串是一种简单而且常用的数据结构。
1、String类
String表示一个字符串,字符串是常量,一旦创建就不能修改;
String是被final修饰的,最终类,所以String不能被继承;
String调用方法修改内容的时候,如果内容不会改变,就直接返回原来的String对象,
如果有改变会产生新对象;
String如果用+运算,标示字符串的连接运算,字符串的连接运算会产生大量新对象,消耗内存;
如果有频繁的做字符串连接,建议用StringBuffer或者StringBuilder
。
2、创建字符串,即定义字符串变量
1)字符串常量赋值给字符串变量
String str = "abc";
"abc"常量,是一个字符串对象,在内存的常量池中
2) 字符串对象赋值给字符串变量
String str = new String("abc");
new String("abc")创建一个字符串对象,在内存的堆中
a)检查常量池中是否存在"abc"字符串对象,若不存在创建一个字符串对象(常量池中),若存在就不创建,
使用已存在的字符串对象;
b)堆中新建一个字符串对象,并将字符常量的值(字符数组)赋值给该对象。
3)字符串方法,详细查看API
作业:
1、解析字符串数据,封装成一个对象
创建方法splitData(String data),解析字符串,字符串方法调用时传递;
创建VO类Student,封装的对象
比如:传过来的参数是"name=zhangsan;number=3;score=123"
把里面所有的东西分离出来,
然后封装成一个student的实例
2、设计程序对“密码”字符进行加密
算法:大写字母或小写字母或数组首尾交换。
'A' + 25 --> 'Z'
'A'+('A'-'B'+25) --> 'Y'
3、设计程序过滤“不文明”词汇
要求:词汇有n个字符就有n个*。
一、StringBuffer类 可变字符串、缓冲字符串
用final修饰的,不能继承
线程安全的可变字符序列。
一个类似于 String 的字符串缓冲区(char数组,默认16个字符)。
用stringBuffer来做字符串的处理,不会产生大量的新对象,对内存消耗小,提高了效率。
每个字符串缓冲区都有一定的容量。只要字符串缓冲区所包含的字符序列的长度没有超出此容量,就无需分配新的内部缓
冲区数组。如果内部缓冲区溢出,则此容量自动增大(一倍)。
重要的方法: append方法,insert方法,delete方法,length方法,toString方法。
String与StringBuffer的区别:
String 不可变得字符串
修改字符串的值会产出一个新的字符串对象;
频繁修改字符串,产生大量的字符串对象,占用大量的内存空间。
用一个最终的字符数组(char[])来存放字符,字符数组变量不能再次赋值;
字符串相加,字符串长度增加,字符数组长度也增加;
但是数组长度定义时就确定,不能改变,只能创建新的数组(长度=字符串长度),再重新赋给字符数组变量;
字符数组变量不能再次赋值,所以只能创建一个新的String对象。
StringBuffer 可变的字符串
修改字符串的值不会产生新的字符串对象;
频繁修改字符串,不会产生新的字符串对象,节省了内存空间。
用一个可变字符缓冲数组存放字符,不是最终的,字符数组变量可以再次赋值;
字符数组有默认容量(默认长度:16);
字符串相加,长度未超过容量(<=容量),容量不改变,即不会新的字符串数组;
字符串相加,长度超出容量,容量自动增加一倍( (容量+1)*2 );创建长度是原来一倍的新数组,再赋值给
字符数组变量。
StringBuilder类
一个可变的字符序列。此类提供一个与 StringBuffer 兼容的 API,但不保证同步(不保证线程安全)
StringBuffer与StringBuilder的区别:
StringBuffer是线程安全的,运行效率较慢。
StringBuilder是线程非安全的,运行效率较快。
二、==操作符与equals()方法
1、==用于比较引用数据类与基本数据类型,equals比较引用数据类型;
2、两者均可比较引用数据类
== 比较的是对象在栈中的引用;
equals()方法默认情况下,比较的是对象在栈中的引用;
equals()方法是类从Object类继承的,即可以重新equals()方法,使其按对象的值比较;
比如:String类重新equals()方法,使字符串对象按值比较。
三、Object类中的方法
equals()方法
hashcode()方法
getClass()方法
toString()方法
四、Wrapper类(封装类)
用于封装基本数据类型的类,即基本数据类型以类的形式体现。
1.4- 手动装箱与拆箱
装箱
Integer inte = new Interger(10);
拆箱
int i = inte.intValue;
1.5+ 自动装箱与拆箱
装箱
Integer inte = 10;
拆箱
int i = inte;
八大基本数据类,拥有八个封装类
Byte
Short
Integer
Long
Float
Double
Boolean
Character
常用封装类进行:基本数据类型与字符串进转换。
五、Math类
Math类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。
ceil(double a) //返回大于等于并最接近参数的整数
floor(double a) //返回小于等于并最接近参数的整数
round(double a) //返回最接近参数的整数,四舍五入
max(double a, double b) //返回两个参数中最大值
min(double a, double b) //返回两个参数中最小值
abs(double a) //返回绝对值
pow(double a, double b) //返回第一个参数的第二个参数次幂的值,即a的b次方
random() //返回随机数,该值大于等于 0.0 且小于 1.0
六、Class类
Class类的实例表示正在运行的 Java 应用程序中的类和接口。
一个类(A类)第一个对象创建时,JVM自动加载这个类,生成该类一个Class类型的对象,这个对象封装该类(A类)的基本
信息,比如:类名、属性名、属性的类型、访问权限、方法名、返回值类型、方法访问权限等。
即Class类的对象用于封装一个类的基本信息。
常用于反射机制。
七、单例模式
一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
一个类在一个系统执行过程中只有一个对象。
实现单例模式遵守三大原则:
1)定义一个私有的、静态的、本类类型的变量;
2)定义一个私有的构造方法;
3)定义一个公共的、静态的、返回本类类型的方法。
class Singleton{
private static final Singleton st=new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return st;
}
}
单例模式分类:
饿汉模式
饱汉模式、懒汉模式
八、Random类
随机数生成器
nextInt()
nextInt(int n) //n是数的范围 0...n(不包括)
九、UUID类
UUID 表示一个 128 位的值,随机的、16进制
常用UUID生成32位16进制数值得随机字符串(+ 4个短直线分隔);此类字符串一般用于做ID。
UUID.randomUUID().toString();
十、Date类
时间类——类 Date 表示特定的瞬间,精确到毫秒(ms)
构造方法
Date(); //获得当前时间对象
Date(long date); //获得指定时间的时间对象,根据date(距1970-1-1 00:00:00:000毫秒数)进行计算
扩展:DateFormat、SimpleDateFormat类格式化时间
常用方法
getTime() //当前时间 距 距1970-1-1 00:00:00的毫秒数
十一、Calendar类
日历类
常用方法
getInstance(); //获得日历对象
set(int year, int month, int day, ...); //设置日期
getTime(); //获得日历上当前日期
get(int field); //获取日历上当前日期的指定字段值(年、月、日、时...)
set(int field, int value); //给日历上日期的某个字段设值
roll(int field, int amount); //向指定日历字段添加指定(有符号的)时间量
十二、对象的销毁
1、局部变量如何销毁
局部变量是方法中变量,生命周期就是方法的执行的一个过程;
方法执行结束,局部变量会被立即从栈中销毁。
2、实例变量如何销毁
实例变量存在对象中,依附于对象存在,对象在,实例变量就存在;
对象销毁时,实例变量就会被销毁。
3、对象如何销毁
若一个对象成为无用对象(在栈中没有对该对象的引用、没有其他对象对该对象的引用),就会被销毁;
不是马上销毁,而是下一次资源回收时销毁。
4、资源回收机制
1、系统(JVM)自动调用,周期性;
2、程序员无法干预,比如:干预如何回收、回收那些东西。
3、System.gc(); //运行垃圾回收器,进行一次资源回收
4、finalize(); //一个对象被销毁时,自动调用该方法,一般用于进行资源清理操作