Java的常量与变量
主要内容:标识符,关键字,变量,数据类型,类型转换,常量
例如:
public yhc;
public class hello{
public static void main(String[] args){
System.out.println("hello");
}
}
标识符
1、标识符:类的名字(class后面的hello,其中每个字母叫字符)
标识符的命名规则:
· 标识符由字母、数字、下划线、美元符组成,注意不能以数字开头,不能是空格键。
· 严格区分大小写
· 不能是Java的关键字(如紫色的字 )、或保留字
· 命名最好反应其作用
关键字
2、关键字(不用死记,大概了解)
48个关键字:abstract、assert、boolean、break、byte、case、catch、char、class、continue、default、do、double、else、enum、extends、final、finally、float、for、if、implements、import、int、interface、instanceof、long、native、new、package、private、protected、public、return、short、static、strictfp、super、switch、synchronized、this、throw、throws、transient、try、void、volatile、while。
2个保留字(现在没用以后可能用到作为关键字):goto、const。
3个特殊直接量:true、false、null。
变量
3、变量
变量的三个元素:变量类型,变量名,变量值
例子:酒店的房间可以理解为变量
客人——>存储的数据,即 变量值
房间的名字(101、102)——>变量名
房间的类型(标准件、单人间、双人间)——>变量类型
很多的房间是单人间,所以 一个变量类型可以有多个变量名
通过房间的名字可以定位客人的信息和房间类型,所以可以通过变量名来快速定位
变量的命名:
· 满足标识符命名规则
· 符合驼峰法命名规范(驼峰式命名法就是当变量名或函式名是由一个或多个单词连结在一起,而构成的唯一识别字时,第一个单词以小写字母开始;第二个单词的首字母大写或每一个单词的首字母都采用大写字母,例:myFirstName、myLastName,这样的变量名看上去就像驼峰峰一样此起彼伏,故得名。)
· 尽量简单,做到见名知意
· 变量名的长度没有限制
数据类型
4、数据类型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cqtdUcUO-1585903051975)(file:Users/yehaocheng/Library/Group%20Containers/UBF8T346G9.Office/TemporaryItems/msohtmlclip/clip_image001.png)]
基本数据类型:
数据类型 | 字节 | 说明 |
---|---|---|
byte | 1 | 字节型 |
short | 2 | 短整型 |
int | 4 | 整型 |
long | 8 | 长整型 |
float | 4 | 单精度浮点型 |
double | 8 | 双精度浮点型 |
char | 2 | 字符型 |
boolean | 4 | 布尔型 |
封装
schoolProj
定义
- 将类的定义的某些信息隐藏在类内部,不允许外部程序直接访问
- 通过该类提供的方法来实现隐藏信息的操作
- 隐藏对象的信息
- 流出访问的接口
静态static关键词
static:静态 静态成员、类成员
static修饰的成员,无论这个类最终实例化出多少对象都会共用同一块静态空间
例如:如果静态定义价格
public static int price{
}
对象实例化时:one.price=10;two.price=20;
最后one 和two的price时都是20,因为他们公用同一块静态空间。
静态的特点
-
类对象共享
-
类加载时产生,销毁时释放,生命周期长
(
static+属性–>静态属性、类属性
静态属性的调用可以是直接 类名.price
static+方法–>类方法
类方法的调用可以是 对象名.方法 也可以类名.方法
推荐调用方式为 类名.静态成员
而类名前不能加 static
方法内的局部变量前也不能加 static
编写方法体时可以调用静态属性
代码块
普通代码块(在方法中定义):
- 顺序执行,先出现,先执行
构造代码块(直接在类中定义):
- 创建对象时调用,优先于构造方法执行
- 可以创建多个,顺序执行
静态代码块(在构造代码块前加static):
- 类加载时调用,优先于构造代码块执行
- 可以创建多个,顺序执行
在创建多个对象时,静态代码块只执行一次,构造代码块在每次实例化的时候都会执行一次 ,所以如果有些代码仅希望执行一次,那么则可以写在静态代码块中,来提高效率
在类中,构造代码块可以给普通属性和静态属性赋值,但是在静态代码块中只能给静态属性赋值
继承
AnimalProj objectProj
继承
-
一种类与类之间的关系
-
使用以存在的类的定义作为基础建立新类(已存在的类叫父类或基类,新建的类叫子类或派生类)
-
新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但是不能选择性的继承父类(一旦选择父类,就必须承接父类的所有开放的特征,没有选择的余地)
-
子类只能继承父类非私有的属性
-
父类无法访问子类的方法
-
兄弟类中不能相互访问
继承的关系
·满足“A is a B“的关系就可以形成继承关系 例如cat、dog is animal,student、teacher is people,
继承的实现
通过extends关键字来实现
-编写父类:
class Animal{
//公共属性和方法
}
-编写子类,继承父类:(单继承,一个子类只能继承一个父类)
class Dog extends Animal{
//子类特有的属性和方法
}
class Cat extends Animal{
//子类特有的属性和方法
}
子类对于父类的方法重写
方法重载
- 同一个类中
- 方法名相同,参数列表不同(参数顺序,个数,类型)
- 方法返回值、访问修饰符任意
- 与方法名的参数无关
例如:
private String sleep(String name) {
}
public void sleep(String name,int month) {
}
public void sleep(int month,String name) {
}
public void sleep(int name,String month) {
}
第一个,第二个,第三个都可以但是第四个与第三个参数类型同时int 和String,所以这两个则不行
方法重写
语法规则:
-
返回值
-
方法名
-
参数类型、顺序、个数
都要与父类继承的方法相同
方法重写:
1、有继承关系的子类
2、方法名相同,参数列表相同(参数顺序,个数,类型),方法的返回值相同
3、方法的访问修饰符是可以允许有变化的,条件是重写的访问范围需要大于等于父类的访问范围
4、与方法的参数名无关
5、父类的构造方法不能被继承,不允许重写,但是会影响子类的实例化
当子类重写父类方法后,子类对象调用的是重写后的方法
对于属性,子类中可以定义与父类重名的属性,并且调用时调用子类中的
子类可以定义与父类重名的属性
访问修饰符
- 共有的:public
- 私有的:private
- 受保护的:protected
- 默认
private:只允许在本类中进行访问
public:允许在任意位置访问
protected:允许在当前类、同包子类/非子类、跨包子类调用,跨包非子类不允许
默认:允许在当前类、同包子类/非子类 调用,跨包子类/非子类不允许
访问修饰符 | 本类 | 同包 | 子类 | 其他 |
---|---|---|---|---|
private | √ | |||
默认 | √ | √ | ||
protected | √ | √ | √ | |
public | √ | √ | √ | √ |
从上至下:访问范围加大,限制能力减小
super关键字
super关键字是对于父类对象的应用
- 代表父类的引用
—访问父类的成员方法 super.print()
—访问父类的属性 super.name
—访问父类的构造方法 super()
子类的构造的过程中必须调用其父类的构造方法
如果子类的构造方法中没有显示标注,则系统默认调用父类无参的构造方法
如果子类的构造方法中即没有显示标注,且父类中没有无参的构造方法,则编译显示错误
使用super调用父类的指定构造方法,必须在子类的构造方法的第一行
this和super对比
this:当前类对象的引用
- 访问当前类的成员方法
- 访问当前类的成员属性
- 访问当前类的构造方法
- 不能在静态方法中使用
super:父类对象的引用
-
访问父类的成员方法
-
访问父类的成员属性
-
访问父类的构造方法
-
不能在静态方法中使用
继承后的初始化顺序
父类的静态成员–>子类静态成员–>父类对象的构造–> 子类对象的构造
父类的静态代码块
子类的静态代码块
父类的构造代码块
父类的无参构造方法
子类的构造代码块
子类的无参构造方法
访问修饰符不影响成员加载顺序,跟书写位置有关
子类构造默认父类的无参构造方法
如果需要使用父类的带参构造,则需要用到super()关键词,形式: super(参数),super()必须放在子类构造方法有效代码的第一行
Object类
- Object是所有类的父类
- 一个类没有使用extends关键字明确标识继承关系,则默认继承Object类(包括数组)
- Java中的每个类都可以使用Object中的定义的方法
equals测试:
- 继承Object中的equals方法时,比较的时两个引用是否指向同一个对象
- 子类可以通过重写equals方法的形式,改变比较的内容
toString测试:
- 输出对象名时,默认会直接调用类中的toString
- 继承Object中的toString方法时,输出对象的字符串表示形式:类型信息+@+地址信息
final关键字
- final class: 该类没有子类 public final class/final public class
- final 方法:该方法不允许被子类重写,但是可以正常被子类使用
- final 方法内局部变量:只要在具体被使用之前进行赋值即可,一旦赋值不允许被修改
- final 类中成员属性:赋值过程:1.定义直接初始化 2.构造方法 3.构造代码块
- final 基本数据变量:初始赋值后不能更改
- final 引用类型变量:初始化后不能再再指向另一个对象,但是对象的内容可以改变
- 可匹配static使用,全局不变
- 使用final修饰可以提高性能,但是会降低可扩展性
单例模式
singleProj
目的
使得类的一个对象成为该类系统中的唯一实例
定义
一个类有且仅有一个实例,并且自行实例化向整个系统提供
要点
-
某个类只有一个实例
-
必须自行创建实例
-
必须自行向整个系统提供这个实例
实现
-
只提供私有的构造方法
-
含有一个该类的静态私有对象
-
提供一个静态的公有方法用于创建、获取静态私有对象
代码实现方案
- 饿汉式:对象创建过程中实例化
- 懒汉式:静态公有方法中实例化
特点
优点:
- 在内存中只有一个对象,节省内存空间
- 避免频繁的创建销毁对象,提高性能
- 避免对共享资源的多重占用
缺点:
- 扩展比较困难
- 如果实例化后对象长期不使用,系统将默认为垃圾进行回收,造成对象状态丢失
使用场景
- 创建对象时占用资源过多,但同时又需要用到该类对象
- 对系统内资源要求统一读写, 如读写配置信息
- 当多个实例存在可能弓|起程序逻辑错误,如号码生成器
多态
意义
允许不同类的对象对同一消息做出不同的响应。
分类
- 编译时多态:设计时多态方法加载
- 运行时多态:程序运行时动态决定调用哪个方法
(平时说的多态多指运行时多态)
必要条件
- 满足继承条件
- 父类引用指向子类对象
向上转型
向上转型(隐式转型、自动转型)
父类应用指向子类实例,可以调用子类重写父类的方法以父类派生的方法,无法调用子类独有的方法
注意:父类中的静态方法无法被子类重写,所以向上转型之后,只能调用到父类原有的静态方法,如果要使用则需向下转型
小类转型为大类
向下转型
向下转型(强制类型转换)
子类引用指向父类对象,此处必须进行强转,可以调用子类特有的方法
必须满足转型条件才能进行强转
instanceof 关键字
instanceof运算符的前一个操作符是一个引用变量,后一个操作数通常是一个类(可以是接口),用于判断前面的对象是否是后面的类,或者其子类、实现类的实例。如果是返回true,否则返回false。
abstract 关键字
抽象类
不允许实例化,可以通过向上转型,指向子类实例
不能与class互换位置
应用场景:某个父类只是知道其子类应该包含怎样的方法,但是无法准确知道这些子类如何实现这些方法
抽象方法
不允许包含方法体,子类需要重写父类的抽象方法,否则子类也是抽象类
使用规则
- abstract定义抽象类
- 抽象类不能直接实例化,只能被继承,可以通过向上转型完成对象实例
- abstract定义抽象方法,不需要具体实现
- 包含抽象方法的类是抽象类
- 抽象类中可以没有抽象方法
- static final private 不能与abstract共存
接口
- 接口定义了某一批所需要遵守的规范
- 接口不关心这些类的内部数据,也不关心这些数些类里方法的实现细节,这只规定这些类里必须提供某些方法
接口的访问修饰符:public 默认
接口中抽象方法可以不写abstract关键字,访问修饰符默认public
当类实现接口时,需要去实现接口中的所有抽象方法,否则需要将该类设置为抽象类
接口中可以包含常量,默认public static final
interface关键词
接口通过interface关键词实现
语法:[修饰符] interface 接口名[extends 父接口1,父接口2]
接口继承
接口可以实现继承,并且可以继承多个父接口
default关键字
default:默认方法 可以带方法体
可以在实现在类中重写,并可以通过接口的引用调用
static 关键字
static :静态方法可以带方法体
不可以在实现类中的重写,可以通过接口名调用
内部类
- 在Java中,可以将一个类定义在另一个类里面或者一个方法中,这样的类叫内部类
- 与之对应,包含内部类的类被称为外部类
- 内部类隐藏在外部内更好的实现了信息隐藏
内部类的分类
- 成员内部类
- 静态内部类
- 方法内部类
- 匿名内部类
成员内部类
-
内部类中最常见的就是内部类,也称为普通内部类
public class Peoson { //外部类:人 int age;//年龄 public Heart getHeart(){ return new Heart(); } //内部类:心脏 class Heart{ public String beat(){ return "心脏在跳动"; } } }
-
内部类在外部使用时,无法直接实例化,需要借由外部类信息才能完成实例化
- new 外部列.new 内部类
- 外部对象.new 内部类
- 外部类对象.获取方法
Person lili=new Person();
Person.Heart myHeart=new Person().new Heart();//方案一
myHeart=lili.new Heart();//方案二
myHeart=lili.getHeart();//方案三
- 内部类的访问修饰符,可以任意,但是访问范围会受到影响
- 内部类可以直接访问外部类的成员;如果同时出现同名属性,优先访问内部类中定义的
- 可以使用 外部类.this.成员的方式,访问外部类中同名的信息
- 外部类访问内部类信息,需要通过内部类实例,无法直接访问
- 内部类编译后.class文件命名:外部类$内部类.class
静态内部类
-
静态内部类对象可以不依赖于外部类对象,直接创建
public class Person { //外部类:人 int age;//年龄 } public Heart getHeart(){ return new Heart(); } //静态方法类:心脏 public static class Heart{ public String beat(){ return "心脏在跳动"; } } }
-
获取静态内部类对象实例
Person.Heart myHeart=new Person.Heart();
System.out.println(myHeart.beat());
- 静态内部类中,只能直接訪向外部类的静态成員,如果需要調用非静态成員,可以通过対象实例
- 静态内部类対象实例吋,可以不依頼于外部类対象
- 可以通辻 外部类.内部美.静态成員的方式,訪向内部类中的静态成員
- 当内部类属性与外部类属性同名吋,默认直接調用内部类中的成員;
如果需要访问外部类中的静态属性,則可以通辻 外部类.属性 的方式;
如果需要访问外部美中的非静态属性,則可以通辻 new 外部美().属性 的方式;
方法内部类
-
定义在外部类方法中的内部类,也称局部内部类
public class Person { //外部类:人 int age;//年龄 public void eat() { } public Object getHeart(){ class Heart{ public String beat(){ return "心脏在跳动"; } } return new Heart();
-
定义在方法内,作用范围也在方法内
-
和方法内部成员一样,class前面不可以添加public,private,protected,static
-
类中不能包含静态成员
-
类中可以包含final,abstract(不推荐)修饰的成员
匿名内部类
- 将类的定义与类的创建,放在一起完成
- 适用场景
- 只用到类的一个实例
- 类的定义后马上用到
- 给类命名并不会导致代码更容易被理解
- 匿名内部类没有类型名称、实例对象名称
- 编译后的文件命名: 外部类$数字.class
- 无法使用private、public、abstract、static修饰
- 无法编写构造方法,可以添加构造代码块
- 不能出现静态成员
- 匿名内部类可以实现接口也可以继承父类,但是不可以兼得
异常
ExceptionProj
try
捕获异常
catch
对于try块捕获的异常进行处理
finally
无论是否发生异常代码总能执行
throws
声明将要抛出何种类型的异常
- throws语句用在方法定义时声明该方法要抛出的异常类型
- 当方法抛出异常列表中的异常时,方法将不对这些类型及其子类类型的异常作处理,而抛出调用该方法的方法,由他去处理
throw
将产生的异常抛常
- 例如:throw new IOException
- throw 抛出的只能够是抛出类Throwable或者其子类的实例对象
- throw抛出异常异常对象的处理方案
- 通过try,catch 包含throws语句–自己抛出自己处理
- 通过throws在方法声明出抛出异常类型–谁抛出谁处理–调用者可以自己处理,也可以继续上抛
- 此时可以抛出与抛出与throw对象相同的类型或者其父类,不能为子类
自定义异常
定义一个类,去继承Throwable类或者他的子类
集合
Java中的集合是工具类,可以存储任意数量的具有共同属性的对象
应用场景
- 无法预测存储数据的数量
- 同时存储具有一对一关系的数据
- 需要数据的增删改
- 数据重复问题
集合框架的体系结构
CollectionProj
Collection
类的对象
三个子接口:
- List (有序,允许重复)----》ArrayList LinkedList
- Queue(有序,允许重复)----》LinkedList
- Set(无序,不允许重复)-----》HashSet
Map
键值对
Map—》HashMap
List
- List是元素有序并且可以重复的集合,成为列表
- List可以精确的控制每个元素 的插入位置,或者删除某个位置的元素
- List的两个主要实现类是ArrayList和LinkedList
ArrayList
- ArrayList底层由数组实现的
- 动态增长,以满足应用程序的需求
- 在列表尾部插入或删除数据非常有效
- 更适合查找或更新元素
- ArrayList中的元素可以为null
set
- Set是元素无序并且不可以重复的集合,被称为集
HashSet
- HashSet是Set的一个重要实现类,称为哈希集
- HashSet中的元素无序并且不可以重复
- HashSet中只允许一个null元素
- 具有良好的存取和查找性能
Iterator(迭代器)
- Iterator接口可以以统一的方式对各种集合元素进行遍历
- hasNext()方法检测集合中是否还有下一个元素
- next()方法返回结合中的下一个元素
Map
- Map中的数据以键值对(key-value)的形式存储的
- key-value以Entry类型的对象是以存在
- 可以通过Key值快速地查找value
- 一个映射不能包含重复的键(key的值不能重复,但是value的值可以重复,一个value可以对应多个key)
- 每个键最多只能映射到一个值
HashMap
- 基于哈希表的Map接口的实现
- 允许使用null值和null键
- key不允许重复
- HashMap中的Entry对象是无序排列的
线程
ThreadProj
进程概念:进程是指执行程序并存放计算机存储器的一个指令序列,它是一个动态执行的过程
线层是比进程还要小的运行单位,一个进程包含多个线程
线程可以理解为一个子程序
- 什么是多线程
- 线程的创建
- 线程的状态和生命周期
- 线程的调度
- 同步与死锁
线程的创建
- 创建一个Thread类,或者Thread子类的对象
- 创建一个实现Runnable接口的类的对象
Thread类
- Thread是一个线程类,位于java.lang包下
sleep方法
- Thread类的方法
public static void sleep(long millis);
- 作用:在指定的毫秒数内让正在执行的线程休眠(暂时执行)
- 参数为休眠的时间,单位为毫秒
join方法
-
Thread类的方法
public final void join();
作用:等待调用该方法的线程结束才能执行
-
Thread类的方法
public final void join(long millis);
作用:等待该线程终止的最长的时间为millis毫秒
Runnable接口
- 只有一个方法run();
- Runnable是Java中用以实现线程的接口
- 任何实现线程功能的类都必须实现该接口
线程的状态
- 新建(New)
- 可运行(Runnable)
- 正在运行(Running)
- 阻塞(Blocked)
- 终止(Dead)
线程的生命周期
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7D4zMZ9H-1585903051978)(/Users/yehaocheng/Library/Containers/com.tencent.qq/Data/Library/Caches/Images/BA4AA1B796F0A0E038F3B8DD8BE7C993.png)]
多线程运行问题
- 各个问题是通过竞争CPU时间而获得运行机会
- 各线程什么时候得到CPU时间,占用多久,是不可预测的
- 一个正在运行着的线程在什么地方被暂停是不确定的
Java输入输出流
流
IOproj
流就是指一连串流动的字符,以先进先出的方式发送信息的通道
输出流
输入流
主要内容
- File类的使用
- 字节流
- 字符流
- 对象的序列化和烦序列化
File类
文件可认为是相关记录或者放在一起的数据的集合
在Java中,使用java.io.File类对文件进行操作
字节流
字节输入流
FIleInputStream
- 从文件系统中的某个文件中获得输入字节
- 用于读取图像数据之类的原始字节流
字节输出流
OutputStream
字符流
对象序列化
- 步骤
- 创建一个类,继承Serialzable接口
- 创建对象
- 将对象写入文件
- 从文件读取对象信息
- 对象输入流
- 对象输出流
序列化:把java对象转化为字节序列的过程
反序列化:把字节序列回复为java对象的过程