Java知识总结
数据类型扩展
整形扩展:
1 | int i=10;//十进制10 |
浮点数扩展:
浮点数会存在舍入误差(精度丢失),因此无法准确表示。
1 | float a1=0.1f; |
因此尽量避免使用浮点数,永远不要对浮点数进行是否相等的判断
字符扩展:
char类型可以强制转换为整形,其值为对应的ASCII码值
- 所有的字符本质还是数字
- char类型使用 Unicode 编码,占两个字节
布尔类型扩展:
在c++中,true,false分别与1,0等价,在Java中不等价
转义字符:
1 | \t //空格 |
类型转换
类型由低到高:
Byte——》short——》char——》int——》long——》float——》double
运算时,不同类型的数据会转换成同一类型(转换成最高级的)
- 类型由低到高,可以发生自动转换
- 类型由高到低,不能发生自动转换,可以用强制转换
- 高类型向低类型转换的时候可能存在内存溢出,精度丢失的问题
- 布尔类型不能发生转换
Java包机制
包的本质是一个文件夹
尽量不要让包里面的名字重复
生成包: package
导入包:import
break,continue和goto
break用于强制退出循环,break后循环不再执行
continue用于结束本次循环,即不再执行后面的语句转而执行下一次循环条件的判断
1 | public static void main(String[] arg){ |
“goto”:用于从内层循环跳到外层循环,不要使用!!!
先定义标签:标签名+冒号
continue 标签名; break 标签名;
1 | flag:for(int j=0;j<5;j++){ |
方法
Java的方法类似于其他语言的函数,是一段用来完成特定功能的代码片段
- 是解决一类问题的步骤的有序集合
- 方法包含于类或对象中
- 方法在程序中被创建,在其他地方被引用
方法的所有部分:
- 修饰符
- 返回值类型
- 方法名
- 参数类型
- 方法体
方法重载:
方法重载的规则:
- 方法名必须相同
- 参数列表必须不同(类型,个数,顺序)
- 方法的返回类型不能作为方法重载的依据
遇到方法重载时,编译器会根据调用方法的参数个数、类型、顺序等逐一匹配,调用最适合的方法,如果匹配失败,则编译器报错
可变参数
有时候,无法确定方法的参数有几个时,可以使用可变参数。可变参数在方法中会变成数组
- 语法:参数类型…参数名
- 一个方法最多只能有一个可变参数
- 方法的可变参数在参数列表中要处于其他参数的后面(即最后一个)
示例:
1 | public static void main(String[] arg){ |
数组
定义数组的语法(一维数组):
数据类型[] 变量名; //声明一个数组
变量名=new 数据类型[数组长度];//创建一个数组
获取数组的长度:数组名.length;
示例:
1 | int[] nums; |
数组的三种初始化
静态初始化
1 | int[] arr={1,2}; |
动态初始化
1 | int[] nums=new int[10]; |
默认初始化
1 | //动态初始化中包含默认初始化。例如当动态初始化的整形数组为赋值时,默认值为0 |
二维数组
1 | int[][] nums=new int[1][2]; |
用户交互Scanner
用Scanner来获取用户输入
- 使用Scanner要导包:java.util.Scanner
- 创建一个扫描器对象,用于接收用户的输入
1 | Scanner sc=new Scanner(System.in); |
-
用hasNext()与hasNextline()可以判断是否还有输入的数据
-
用完scanner,使用.close()关闭Scanner,节省资源
1
2Scanner sc=new Scanner(System.in);
sc.close();
Scanner的接收器
- .next() 接收字符串,遇到空格或回车会停止
- .nextLine() 接收字符串,可以读取空格,遇到回车停止
- .nextInt() 接收下一个整数,可以使用hasNextInt()判断输入是否合法
- .nextFloat() 接收下一个浮点数,可以使用hasNextFloat判断输入是否合法
- 还有其他很多接收器
1 | public static void main(String[] arg){ |
1 | 输出: |
Array类
使用时要导包 import java.util.Arrays
Arrays为静态类,可以不用实例化直接使用
-
.toString(数组名) 打印数组
1
2
3
4public static void main(String[] arg){
int[] a={1,2,3,1,4,5,6,777,8};
System.out.println(Arrays.toString(a));
}输出:
1
[1, 2, 3, 1, 4, 5, 6, 777, 8]
-
.sort(数组名) 快速排序数组
1
2
3
4
5public static void main(String[] arg){
int[] a={1,2,3,1,4,5,6,777,8};
Arrays.sort(a);
System.out.println(Arrays.toString(a));
}输出:
1
[1, 1, 2, 3, 4, 5, 6, 8, 777]
-
.fill(数组名,开始位置,结束位置,替换的值) 把指定位置替换成指定的值(不指定位置则全部替换)
1
2
3
4
5public static void main(String[] arg){
int[] a={1,2,3,1,4,5,6,777,8};
Arrays.fill(a,0,4,77 );
System.out.println(Arrays.toString(a));
}输出:
1
[77, 77, 77, 77, 4, 5, 6, 777, 8]
Integer类
Integer对象的方法
Integer.parseInt(“”);是将字符串类型转换为int的基础数据类型
Integer.valueOf(“”)是将字符串类型数据转换为Integer对象
Integer.intValue();是将Integer对象中的数据取出,返回一个基础数据类型int
稀疏数组
当一个数组有大量的重复数值(比如0)时,可以使用稀疏数组的结构来储存。
- 稀疏数组的结构
- 一个二维数组
- 第零行存了数组的行数、列数、默认值
- 从第一行开始,每行存储数组中非默认值的位置的信息(在第几行,在第几列,值为多少)
面向对象之-封装
-
该藏的藏起来:
程序设计追求“高内聚,低耦合”。高内聚即类的内部数据操作细节自己完成,不让外部干涉。低耦合即暴露少量的方法给外部使用
-
封装:即数据的隐藏
通常,应该禁止直接访问一个对象中数据的实际表示,而应该通过操作接口来访问
-
属性私有,通过get/set来操作
利用alt+insert键快速生成get/set方法
1 | public class TrainingCharactor { |
面向对象之-继承
- 继承是类与类之间的关系
- 继承关系的两个类,一个为子类(派生类),一个为父类(基类),子类继承父类,使用关键字extends来表示
- 子类和父类之间具有“is a”的关系
- 父类的构造方法不能被继承!!!
- 静态方法可以被继承,但无法被重写
ctrl+h可以打开继承关系树
Java中,所有的类都默认继承自Object类
Java中只有单继承!
super()
super()使用实例:子类想要访问父类的方法或属性时,可以使用super.来访问
示例:
1 | class A{ |
super()使用实例:子类的构造方法中
编译器会自动在子类构造函数的第一句加上 super(); 来调用父类的无参构造器;此时可以省略不写。如果想写上的话必须在子类构造函数的第一句。
在子类的构造方法前,会默认地加入父类的无参构造方法super(),此时如果父类定义了有参构造而没有定义无参构造,会报错。
可以通过super来调用父类其他重载的构造方法,只要相应的把参数传过去就好
示例:
1 | class A{ |
1 | class B extends A{ |
方法重写与重载
重写:
重写的注解:@override
重写的前提:要有继承关系,子类重写父类的方法:
特点:
- 方法名必须相同,方法体不同
- 参数列表必须相同
- 修饰符的范围可以扩大,但不能缩小
- 抛出的异常可以被缩小,但不能扩大
静态方法可以被继承,但无法被重写!!!
重载:
方法重载的规则:
- 方法名必须相同
- 参数列表必须不同
- 方法的返回值类型可以相同也可以不同
- 仅仅是返回类型不同不足以成为方法重载的条件
方法重载应避免歧义调用!!!
多态
多态是方法的多态,属性没有多态
多态存在的条件
-
要有继承关系
-
要有方法重写
-
父类的引用指向子类对象
程序中类型的最终状态在运行中才会确定,即一种动态编译
举个栗子:去街上买水果,不管是苹果还是西瓜,只要是水果就行,这就是一种多态。
- 父类型的引用可以引用子类的对象
- 子类对象可以用在任何需要使用父类对象的地方,这就是多态。
父类型的引用可以指向子类的对象,但一个对象能调用哪些方法主要看左边的引用,和右边关系不大。
instanceof关键字:
可以判断一个对象是什么类型:
1 | public static void m3(Person p3){ |
接口
接口定义的是一组规则,接口只有定义,自己无法写方法
类的定义是用是class,接口的定义是用interface
接口中的所有定义都是抽象的,而且都是public
-
jdk7以前:
- 只能定义全局常量和抽象方法:
- 在 Java 接口中声明的变量其实都是常量(全局变量),接口中的变量声明,将隐式地声明为public static final 变量(并且只能是 public,用 private 修饰会报编译错误),即常量。
- 接口中定义的变量必须初始化。可以省略 public、static 和 final。
- 接口中的所有方法都默认是由public abstract修饰的(抽象方法),只能是 public abstract,其他修饰符都会报错。可以省略public和abstract。
-
jdk8:
- 除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法。
1 | public interface InterFace { |
接口必须需要被实现,可以通过类来实现接口,关键字implements
实现了接口的类,就必须重写接口中的方法
1 | public class InterFaceIMPL implements InterFace{ |
一个类可以实现多个接口,在接口名后加","再加接口名,这变相实现了Java的多继承。
抽象类
关键词:abstract,栗子:
1 | public abstract class Circle { |
抽象类的构造方法访问修饰符为protected,这也表明抽象类无法被实例化
继承自抽象类的子类,必须实现其继承自抽象类父类的方法,否则这个子类仍然是抽象类
即使子类是抽象的,其父类也可以是具体的,例如Object类。
内部类
内部类就是在一个类里面定义一个类。栗子:A类中定义一个B类,则B类就是A类的内部类。
内部类的种类:
-
成员内部类
- 成员内部类可以直接访问外部类的私有属性、方法
-
静态内部类
-
静态内部类则无法访问外部类的属性和方法,除非外部类的属性和方法也为静态。
1
2
3
4
5
6
7
8public class classTraining {
public int a=10;
public void change(int a){};
public static class Inner{
public int innera=a;
}
}//错误1
2
3
4
5
6
7
8public class classTraining {
public static int a=10;
public void change(int a){};
public static class Inner{
public int innera=a;
}
}//正确
-
-
局部内部类
在方法中定义的类就是局部内部类
-
匿名内部类
没有引用名称去保存实例化后的对象
Java异常处理
异常机制
异常,英文是“Exception”,指程序运行中出现的意料之外的情况。
- 检查性异常:例如用户输入错误或打开一个文件但文件不存在。这些异常在编译时不能被简单地忽略。
- 运行时异常:运行时异常可以在编译时被忽略,这种异常是可以被程序员避免的。
- 错误:Error,错误是程序脱离控制的问题。例如栈溢出。它们在编译时是检查不到的。
Java中,万物皆对象,Java把异常当成对象来处理,并定义了一个基类:java.lang.Throwable作为所有异常的超类。
Java API中定义了许多异常类,并分为两大类:错误Error和异常Exception。
Error和Exception的区别
Error通常是致命性的错误,当出现Error时,Java虚拟机(JVM)一般会选择终止线程;Exception通常情况下是可以被处理的,并且程序中应尽可能地去处理这些异常。
-
Error
Error类对象由Java虚拟机生成并抛出。
-
Exception
Exception分支中有一个重要的子类:RuntimeException,运行时异常。
ArrayIndexOutOfBoundsException:数组下标越界
NullPointerException:空指针异常
ArithmeticException:算术异常,如除数为0
MissingResourceException:丢失资源
ClassNotFoundException:找不到类异常
扩展:Java中的异常分类
- Error:一般是系统出错,是免检异常
- Exception:
- ClassNotFoundException:必检异常
- IOException:必检异常
- RuntimeException:运行时异常,为免检异常
异常的捕获和抛出
处理异常的方法:
- 在方法头中声明异常
- 在方法体中抛出异常
- try-catch捕获异常
1.在方法头中声明异常
每个方法都必须声明它可能抛出的必检异常的类型,这被称为声明异常
1 | public static void main(String[] args) throws Exception |
2.在方法体中抛出异常
在一个程序检测一个错误时,可以创建一个恰当的异常类型的实例并抛出它。这被称为抛出异常
1 | NumberFormatException numberFormatException=new NumberFormatException(); |
1 | throw new NumberFormatException(); |
在try-catch块中,捕获的也是一个异常的实例
3.try-catch-finally捕获异常
try语法块里写想要测试的代码
catch语法块里写想要捕获的异常。
-
用catch捕获多个异常时,大的,范围广的异常应该后捕获,小的,范围窄的异常应该先捕获,否则会报错。
1
2
3
4
5
6
7
8
9try {
System.out.println();
}catch(NumberFormatException nfe){
System.out.println("1");
}catch(Exception exp){
System.out.println("2");
}catch(Throwable tra){
System.out.println("3");
}
finally语法块写在最后,用于捕获完异常后的处理。不管异常有没有被捕获,finally语法块里的都会执行。
Java文件读写
存储在程序中的数据是暂时的,为了能够永久储存数据,需要存到磁盘中。在Java中,可以用File类来打开并操作一个文件
1 | File file = new File(//填入文件路径); |
如果文件不存在,可以用.creatNewFile()创建文件
printWriter类:写文件,写完后要.close(),数据才会真正被写入文件
Scanner类:读文件





