Java—笔记
文章目录
- Java—笔记
- 1. 环境配置
- 2. 基础
- 2.1 数据类型
- 2.2 运算符优先级
- 2.3 数组
- 2.4 内存区域的划分
- 2.5 类
- 2.6 类的使用
- 2.7 构造方法
- 2.8 方法的重写【override】:
- 2.9 静态变量 和 静态方法【带有 static 关键字的变量/方法】
- 2.10 单例模式
- 2.11 封装性
- 2.12 Scanner【输入】
- 2.13 匿名对象
- 2.14 ArrayList
- 2.14 Arrays
- 2.15 Math
- 2.16 String类(字符串)
- 2. 17 继承性
- 2.18 方法的重写(Override)
- 2.19 抽象
- 2.20 接口
- 2.21 日期与时间
- 2.22 StringBuffer 与 StringBuilder
- 2.23 异常处理
1. 环境配置
1.1 JDK 安装
1.2 IDEA 的设置
1.2.1 先导——要点
- IDEA 需要引入JDK :修改 SDK
- Java 的文件结构 : 项目 -》模块 -》包
- 包 必须放在模块的 src文件夹下
- 包名 只能是 字母,数字,英文句点,且是一组由 句点分隔 的文件夹
如:cn.itcast.demo01 (表示 文件夹:cn/itcast/demo01)
小结:
- 目录结构:项目 =》 模块 =》 包 =》 java文件
- 快速创建主函数 的快捷方式:
psvm + tab
或者main +tab
1.2.2 编辑器的设置
- 修改默认的代码提示快捷键的设置:
1.2.3 常用快捷键
功能 | 快捷键 |
---|---|
代码提示 | alt + / |
自动导包(修正代码) | alt + enter |
复制光标所在行,并插入到光标的下一行 | ctrl + d |
格式化代码 | ctrl + alt +L |
单行注释 | ctrl + / |
多行注释 | ctrl + shift + / |
自动生成代码(get / set /toString) | alt + insert |
移动当前代码行 | alt + shift + 上下箭头 |
快速写 遍历数组的代码 | 数组名.fori + enter |
快速生成代码块如for | ctrl + alt + T |
2. 基础
2.1 数据类型
char 和 byte 的差别:
- char 是无符号型的,可以表示一个整数,不能表示负数;char可以表中文字符,
- byte 是有符号型的,可以表示 -128—127 的数,byte不可以表中文字符
2.2 运算符优先级
2.3 数组
- 数组直接打印得到的是地址
- 数组反转:对称位置的元素交换
- 数组的初始化
- 静态 [指定内容]
格式: 数据类型 [] 数组名= new 数据类型[]{数组的内容};
例如: int[] arr = new int[]{1,2,4,6};
- 动态[指定长度]
格式:数据类型[] 数组名称 = new 数据类型[长度]
例如:
int[] arr = new int[10];
arr[0] =12;
arr[1] = 15;
arr[2] = 45;
- 省略格式:
数据类型[] 数组名称 = {数组的内容};
例如:int[] arr = {1,2,5,6};
- 拆分称两个步骤:
格式: 数据类型[] 数组名称;
数组名称 = new 数据类型[]{数组内容}; (采用省略格式则不能分步骤写)
例如:
int[] arr;
arr = new int[10]{1,2,5,7,9};
2.4 内存区域的划分
- 栈(stack):存放方法的局部变量,运行方法
【局部变量 的特点:一旦超出作用域就会从内存中消失】 - 堆(heap) :new出来的东西都放在堆中(为:引用类型),如 :数组
【堆内的东西都有一个16进制的地址值】
所有的引用类型都可以赋值为 null ,代表什么都没有
堆内存中的东西都有默认值:
- 整数:0
小数:0.0
字符:’\u0000’
布尔值:false
引用类型:null
- 方法区(method area):存储.class的相关信息,包含方法信息
- 本地方法栈(native method stack)
- 寄存器(register):与cpu相关
2.5 类
- 类:属性+方法【行为】
- JAVA的类:成员变量(属性是写在类 的内部) + 成员方法 //普通变量写在方法内部
- 方法只能有一个返回值,如果想返回多个数,可以将返回值定义为数组,返回数组首地址
- 普通方法 与 成员方法 的区别:
- 普通方法:带static ;
- 成员方法(自定义的类里面的方法): 不带static
- 成员变量 与 (方法内部的)局部变量 的区别:
- 成员变量:类 的内部,在类中都可以使用,有默认值
- 局部变量:方法内部,只能在 方法内部使用,没有默认值,使用要先赋值
- 成员变量 和局部变量 重名 时,
- 默认根据就近原则,优先使用 局部变量
- 如果想使用成员变量,可以使用**this **关键字,如: this.name
- this 一定是写在方法里的,起 在 重名 ** 的情况下作区分变量** 的作用
- 内部类【1个类 定义在 另一个类 内部 =>内部类(public / protected / private)。 外面的类叫外部类(只能public)】
内部类-链接- 内部类的可以访问外部类的所有成员变量和成员方法
- 内部类的分类:
- 成员内部类【不能定义静态成员,只能定义实例成员】
调用成员内部类的属性、方法:
- 成员内部类【不能定义静态成员,只能定义实例成员】
int tmp = outerClass.this.age; // age为属性名
outerClass.this.run(); // run 为 成员内部类的方法
# 实例-main下:
outClass.innerClass in1 = new outClass().new innerClass();
in1.run();
- 静态内部类
outClass.innerStaticClass in_1 = new outClass.innerStaticClass();
in_1.run();
- 方法内部类【定义在 方法中的内部类,不能有static,也不能有权限访问符,可以访问所在方法中带有 final的局部变量】
- 匿名内部类
2.6 类的使用
步骤:
- 导包:
- 创建
- 使用
- 导包:【 import 包名称.类名称 】
// 对于和当前文件同一个包的类,可以不写导包语句
// java.lang 包 下的类也不需要 导包
// import 语句 必须写在 package 语句 后,类名 前
例如:
import java.util.Scanner;
- 创建 :【 类名 对象名 = new 类名() 】
例如:Person p1 = new Person();
- 使用: 对象名.属性名
// 对象名.成员方法
例如:
String name = p1.name;
- 类 可以作为 方法的 参数
- 标准类(JavaBean)的条件:
- 所有成员变量都使用private关键字
- 每个成员变量都编写一对 setter 和 getter 访问器
- 编写一个无参数的构造方法
- 编写一个全参数的构造方法
2.7 构造方法
-
构造方法:专门用来创建对象
-
IDEA编辑器快速生成构造方法:
- IDEA 中可使用 工具栏 code -generate - constructer 来自动生成构造方法
- 构造方法的格式:
public 类名(参数类型 参数名){
方法体
}
例如:
public Person(int age){
this.age = age;
}
构造方法的注意事项:
1.构造方法的名称必须与所在的类的名称完全相同,大小写也要一样
【普通方法首字小写,构造方法首字大写】
2.构造方法不能写返回值类型,连void也不要写
3.构造方法不能return 返回值
4.如果没有写构造方法,那么编译器会自动赠送1个构造方法,
5.只要自己编写了构造方法,编译器就不会赠送构造方法
6.可以在定义构造方法时,将所需的参数定义在方法的参数列表中, 可以在创建对象时传入参数。但是还是需要写get和set 方法,目的是方便修改参数的值。
2.8 方法的重写【override】:
- 方法的重载【只看 方法名称 和 参数类型】(常 在定义语句前+ @Override ,若出错则报错): [方法名称一样,参数列表不一样(参数的个数/类型/类型顺序不同)]
[方法的重载与参数名称/返回值无关]
面向对象的三大特性:
- 封装性(如: private, 方法等)
- 继承性(extend ,super等)
- 多态性(子类继承父类的方法后可以 覆盖重写override)
2.9 静态变量 和 静态方法【带有 static 关键字的变量/方法】
- 静态变量/ 方法 属于整个类,而不仅仅 属于一个对象
- 静态变量/ 方法 可以直接用 类名.变量,而 不用 先创建对象再使用。(也可以创建对象后使用)
- 静态变量/ 方法 只创建1次
- 静态变量/ 方法 不能使用
this
,super
关键字,因为静态方法可以通过类名来调用,而这是可能还没有创建对象,更谈不上继承 - 静态代码块【即:使用static来包裹的语句块】:
static{
//语句块
}
static关键字:
有static,则这个被标识的内容不再属于对象,
而是属于类,凡是本类的对象,都共享一份数据
格式:
public static void PrintMe(){.......}
调用:[对于本类当中的静态方法,可以省略类名称,直接静态方法]
类名称.静态变量
类名称.静态方法()
static 修饰的方法【静态方法】:
1.属于类
2.可以先创建对象,再调用
# 不推荐,因为开发者
可能会 误以为 静态方法
是属于对象的,
并且 会被 javac 翻译成
类名称.静态方法() 来调用
3.也可以直接 类名称.静态方法() 来调用
# 推荐使用
2.10 单例模式
- 单例模式 保证 某个类 只有1个实例(对象),并自行实例化
- 单例模式的特点:
- 单例类 只有1个实例
- 单例类 自己创建自己的实例
- 单例类 向其他对象提供这个唯一的实例
# 单例模式的例子
public class Single{
# 构造方法
public Single(){};
# 创建实例
private static Single instance = new Single();
# get方法
public static Single getInstance(){
return instance;
}
}
2.11 封装性
封装性有两种:【变量,方法】
a.方法
b.private关键字:
只有在写了private 的类中可以直接访问该属性,
有private 就必须在类中
定义一个专门设置该属性的方法
set(int num)【有参数,无返回值】
和一个专门获取该属性值的方法
get()【无参数,有返回值】
2.12 Scanner【输入】
- 导包
- 创建
- 使用
1.导包
import 包路径.类名称;
# 如果使用的类和当前类在同一个包下,可省略导包语句
# 一般情况下,只有java.lang包下的类不需要导包
# 导包语句要在 package 语句之后,public 语句之前 写
2.创建
类名 对象名 = new 类名(参数);
# 例如:Scanner sc = new Scanner(System.in);
# System.in 表示键盘输入
3.使用
对象名.成员方法名(参数)
# 例如接收1个键盘 int 数
# int num = sc.nextInt(); 将接受的字符串转化为int
# String str = sc.next(); 接受字符串
2.13 匿名对象
1. 普通对象的 格式: 如 :
Person person = new Person();
2. 匿名对象 格式:只含有右边,没有左边及赋值运算符 :
new 类名().属性名 = 相关的值;
如:
new Person().name = "小米";
匿名对象 只能使用一次,如果想再使用,必须重新new
# 1.匿名对象
new Dog();
# 2.匿名对象的使用
new Dog().setAge(18);
new Dog().setName("旺财");
2.14 ArrayList
-
与 数组的区别:
- 长度可变;
- 虽然是也是引用类型,但是直接打印得到的是内容;
- 若内容为空,则打印得到 【】
-
泛型:ArrayList<元素类型>
-
ArrayList的<>表示泛型,表示装在集合中的所有元素都是统一的 什么 类型。
-
泛型只能是 引用类型 (即:需要new )
-
基本类型想要用ArrayList存储必须使用包装类
-
JDK1.5开始可以进行自动装箱,自动拆箱:
- 自动装箱: 基本类型 => 包装类
- 自动拆箱: 包装类 => 基本类型
-
包装类 与 基本类型:
泛型的格式:
ArrayList<String> list = new ArrayList<String>();
//从JDK1.7开始,右侧<>内可以不写内容,但要有<>
ArrayList<String> list = new ArrayList<>();
ArrayList的常用方法
add(数据) :
向ArrayList 集合中 添加 数据 ,
返回 true/false
,数据要与 泛型<> 的类型一致 。
对于ArrayList 集合来说,add一定成功,
但其他类型的集合add不一定成功
get(索引号) :
从ArrayList 集合中 获取 元素 ,返回 元素,索引号 从0 开始
remove(索引号) :
从ArrayList 集合中 删除 指定下标的元素 , 返回 被删除的元素
size() :
获取ArrayList 集合的 元素个数
2.14 Arrays
- java.util.Arrays 是一个与数组相关的工具类,提供大量静态方法,实现对数组的操作
- Arrays中常用的静态方法:
- toString(数组):将参数数组按默认格式变为字符串
public static String toString(数组):
将参数数组按默认格式变为字符串
例如:
int[] arr = {20,30,40};
String str = Arrays.toString(arr);
System.out.println(str);
sort():将参数数组按默认升序排序
public static void sort(): 将参数数组按默认 升序排序
【
数值按数字大小排,
字母的字符串按字母顺序排,
自定义类型需要有comparable或comparator接口提供支持
】
例如:
int[] arr1 ={111,22,33};
Arrays.sort(arr1);
System.out.println(Arrays.toString(arr1));
2.15 Math
- java.util.Math 与数学运算相关的工具类,提供大量数学计算相关的静态方法
- 常用的静态方法:
- 取绝对值 abs() :
public static double abs(double num)
- 向上取整 ceil() :
public static double ceil(double num)
- 向下取整 floor():
public static double floor(double num)
- 四舍五入,不带小数点 round():
public static long round(double num)
- double 类型的PI:
Math.PI
- 取绝对值 abs() :
2.16 String类(字符串)
- 所有带 “ ” 的都是字符串对象,可以 有 new 也可以没有 new
- 特点:
1. .java中字符串的内容 永不可变
2. 字符串 是常量,可以共享使用,以节省内存,相当于 char[],在底层是 byte[] - 创建字符串的 4种方式:
# 构造方法为:public String();
# 创建空白字符串
String str0 = new String();
# 构造方法为:public String(char[] arr);
# 根据字符数组的内容创建字符串
char[] chararr = {'a','b','c'};
String str1 = new String(chararr);
# 构造方法为:public String(byte[] arr);
# 根据字节数组的内容创建字符串
byte[] byteArr = {48,65,97};
String str2 = new String(byteArr);
# 直接创建:
String str = "abc";
字符串常量池:
-
程序中所有 " " 的部分都在 字符串常量池中,new 的不在 池 中
-
字符串常量池 位于 堆
-
对于 基本类型来说 == 是进行 值的比较 ,对于引用类型来说 == 是进行 地址的比较
-
引用类型 的 内容的比较【常用的方法】:
equals(任何对象) : 返回 true/false
equalsIgnoreCase() :比较内容(忽略大小写)
如:
String str1 = "abc";
String str2 = "abc";
str1.equals(str2); //true
# 注意:
equals(b) 与 b.equals(a)效果一样,
但是推荐 当 1个常量和1个变量 时,常量写前面,
因为当 .号 前为 null 时会报错【空指针异常】
如:
String str1 = "abc";
"Abc".equals(str1);
- 与获取相关的常用方法:
获取字符串中的字符个数: length():
拼接字符串(相当于str1+str2): concat(字符串)
如: str1.concat(str2);
获取指定位置的字符: charAt(索引)
如:
String str1="hello";
char abc = str1.charAt(1); //abc = e
查找参数字符串在字符串中首次出现的位置,若能没有则-1: indexOf(字符串)
如:
String str1 = "hello";
int abc = str1.indexOf("lo");
截取从参数位置到最后的字符串: substring(索引)
截取从[索引1,索引2)的字符串: substring(索引1,索引2)
如:
String str1 = "hello";
String str2 = str1.substring(0);
//str2 = "hello"
String str3 = str1.substring(1,4);
//str3 = "ell";
- String 的转化相关的常用方法:
# 将字符串拆为字符数组,并将字符数组作为返回值: toCharArray()
# 获取当前字符串底层的字节数组: getBytes()
# 替换字符串,返回新字符串: replace(old,new)
- 字符串的分割
split(正则表达式):
按指定规则分割字符串,并返回字符数组,若想用. 作为分割符,需要写 \\.
- 字符串在内存中的创建过程:
以 String str1 = "abc" 为例 内存中情况
即:
a. 在 栈中开辟 变量的空间,
b. 在 堆中的 字符串常量池 中创建String 对象
c. 在 堆中 创建 byte[]
d. String 对象引用 byte[] 的地址
e. 栈中的变量 引用 String 对象 的地址
2. 17 继承性
- 继承是多态性的前提;
- 承解决了共性的问题(把几个类中都有的属性、方法放到1个父类中,每个子类继承父类类)
- 父类与子类:
1. 父类:也叫基类,超类
2. 子类:也叫派生类 - 在继承关系中,子类就是父类的一种
1. 例如: 父类是员工,子类是老师,老师也是一种员工 =》 老师 is 员工
父类【普通的类的定义】:
public class 父类名称{}
子类:
public class 子类名称 extends 父类名称{}
例如:
//父类
public class Employee {
String name;
int age;
}
//子类
public class Teacher extends Employee {
String Tno;
}
-
继承过程中,成员变量的访问特点【子类有,则优先使用子类的成员变量】:
- 只有子类知道父类的变量、方法。父类不知道子类的变量、方法。子类、父类都没有某个属性时,调用该属性,则会报错。
- 在父、子的成员变量 重名时 且 创建子类对象时,可以有两种访问方式。【假设name属性重名】:
- 直接:
Zi zi = new Zi()
zi.name # 优先使用子类的name
- 间接:
通过方法:
调用了父类的方法。则方法内使用的是父类的变量
- 父类的变量,子类的变量,方法的局部变量 重名时:
- 父类的变量:super.变量名
- 本类的变量: this.成员变量名
- 方法的局部变量: 直接写变量名
2.18 方法的重写(Override)
-
在继承关系中 : 方法名和参数列表都一样
-
**重写(Override) 与重载(Overload) **的区别:
- 重写(Override): 发生在继承关系中,方法名和参数列表【都一样】,覆盖
- 重载(Overload):名称一样,参数列表【不一样】
-
方法覆盖重写的特点:创建的是子类,则 优先使用 子类的方法
@Override :
写在 方法前面,用来检测、是否 是正确有效的覆盖重写,
可以不写,但最好写,这是一种安全措施
即:
如果 方法前写了 @Override,若不是重写方法,则会报错
- 子类的重写方法 的 返回值 必须 小于等于 父类的返回值的取值范围 【即:子集】
- java.lang.Object 类是 所有类的 父类【即 祖宗类】,java.lang.String就是Object的子类
- 子类的方法的权限修饰符 必须 大于等于 父类的 权限修饰符
- 权限修饰符: public > protected > (default,不是关键字) > private
- 小结:子类的权限符 的权限 >= 父类 ,数据类型 <= 父类
- 方法重写的使用场景:
对于已经在使用的类,不去修改,而是通过新定义一个子类,
进行方法的重写,来实现新的功能
- 继承中 构造方法的特点:
- 子类构造方法中,有一个默认的 super();的方法 调用。
所以,一定会先调用父类的构造方法。再调用子类的构造方法- 可以通过 super关键字来调用 父类 的重载构造方法
- 只有子类的 构造方法 可以调用【super()】 父类的构造方法,普通方法不行;
子类的构造方法中,不能同时写两个super();- 子类继承父类后,一定会调用 super(),不写,则会使用默认的super(),
写了,则执行写的: 如: super(123);
- super 关键字的用法:
在子类中要调用父类的属性或方法时:
如: super.age;
super.PrintMe();
在子类中 调用 父类的构造方法 :
super();
- super 与 this 的用法 小结:
super() 和 this()不能 同时写【即:不可共存】
super 关键字的用法:【用来访问 父类】:
在子类中要调用父类的属性或方法时:
如:
super.age;
super.PrintMe();
在子类中 调用 父类的构造方法:
super();
this 关键字的用法:【用来访问 本类】:
调用本类的 成员变量或 成员方法:
如:
this.age;t
his.PrintMe();
调用本类的构造方法 :
如:
在 无参构造方法 内写:
this(123);
# 表示本类的无参构造方法调用了本类的有参构造方法,只用写一次 this(...)且是第一句
2.19 抽象
- 定义:
一个父类有一个没法具体描述的方法:
如:
子类 猫 有 吃鱼() 的方法,
父类 动物 有吃() 的方法。但没法细说
格式:
- 方法 返回值前 加上 abstract 关键字,去掉大括号{},直接以;结束
public abstract void Eat();
- 抽象方法 只能 定义在抽象类内 【在 class前加上 abstract】,但 抽象类不一定有 抽象方法,没有抽象方法的 抽象类 同样 不能直接new,它有特殊用途
//抽象类
public abstract class Animals {
//抽象方法,没有普通方法的{}
public abstract void Eat();
}
- 抽象类与抽象方法的使用:
抽象类的 对象 无法直接 创建(new)
即: 不能 Animal a = new Animal()
必须用一个子类 继承一个父类
4 . 子类 必须 覆盖重写 父类 所有的 抽象方法
【除非子类也是抽象类】:
抽象方法覆盖重写 即:
去掉 抽象方法的 abstract关键字,补上{}
【可以鼠标点击 extends 行 按下 alt + enter】
例如:
public class Cat extends Animals {
@Override
public void Eat(){
System.out.println("cat eat".toUpperCase());
}
}
- 创建子类对象进行使用 【 即: 在main()内进行new 对象 】
- 执行顺序:
1.子类调用super(),执行抽象父类构造方法
2.子类构造方法
3.子类的抽象方法
2.20 接口
- 接口就是各个类的规范,
- 接口是一种 引用的数据类型 ,其中:最重要的是抽象方法
- 格式:
public interface 接口名称{
# 接口内容
}
- 接口内容:
- JDK 1.7 的接口可以包含:
- 常量
- 抽象方法
- JDK 1.8 的接口还可以额外包含
- 默认方法
- 静态方法
- JDK 1.9 的接口还可以额外包含
- 私有方法
- 接口中的抽象方法,修饰符必须是 public abstract 【如:public abstract void methodAbstract();】, 可以省略但不能换成别的 。
- 接口无法直接使用,只能让1个 “实现类” 来 “实现” 该接口 【类似 抽象类的继承】
- 接口使用步骤:
- 格式:
public class 实现类名称 implements 接口名称{
//。。。。。
}
- 接口的实现类必须 覆盖重写(即:实现) 接口类中的所有抽象方法,去掉abstract 关键字,加上{}
【例如: public void methodAbstract(){};】 - 创建 “实现类” 的对象,进行使用
- 【注意事项】:
如果实现类没有覆盖重写接口的所有抽象方法,那么这个实现类必须为抽象类 - JDK 1.8 开始,接口允许定义 默认方法【默认方法:用于解决接口升级的问题】:
//当在接口中新加了1个抽象方法,但 现有的方法已经投入使用,不想更改现有方法时使用
public default 返回值类型 方法名称(参数列表){
#方法体
}
- 接口的默认方法,可以通过 接口实现类的 对象,直接调用 ;
也可以被 接口实现类 覆盖重写
2.21 日期与时间
import java.text.SimpleDateFormat;
import java.util.Date;
public class Demo03 {
public static void main(String[] args) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd:HH-mm");
Date date1 = new Date();
System.out.println(sdf.format(date1));
}
}
2.22 StringBuffer 与 StringBuilder
StringBuffer 和 StringBuilder 都可用来创建字符串,
区别:
- StringBuffer :速度慢,但在多线程时安全
- StringBuilder :速度快,但在多线程时不安全【StringBuilder 更常用】
public class Demo{
public static void main(String args[]){
# 10 为容量
StringBuilder sb_1 = new StringBuilder(10);
sb_1.append("大家好");
System.out.println(sb_1);
sb.insert(8, "Java");
System.out.println(sb_1);
# 5为开始位置,8为结束位置
sb.delete(5,8);
System.out.println(sb_1);
}
}
2.23 异常处理
int a=10;
int b=0;
try{ // 尝试运行
int c = a/b;
System.out.println(c);
}catch (ArithmeticException exce){ // 捕获异常,采取相应的措施
System.out.println(exce);
}catch (Error err){ // 捕获错误
System.out.println(err);
}
finally { // 无论是否有异常都执行
System.out.println("end");
}
- 自定义异常
简而言之:
- 捕获并处理异常=》try-catch
- 只抛出,不处理 =》 在定义出使用 throws 指定的异常
# 自定义异常:
# 1.编写异常类【成员变量+构造方法+返回错误信息的方法】
# 2.在定义1个方法时,指定要抛出的异常的类
# 3.调用方法时,try-catch
//*************************
class myException extends Exception{
# 规定:当details>10时,抛出异常
private int details;
public myException(int a) {
this.details=a;
}
@Override
public String toString() {
return "我的自定义异常:details="+details;
}
}
//*************************
class Test{
public static void run(int a)throws myException {
if(a>10){
throw new myException(a); //抛出一个异常对象
}
System.out.println("ok");
}
}
//*************************
public static void main(String[] args) {
try{
Test.run(20);
}catch (myException e){
System.out.println(e);
}
}