目录
1. 初始Java
1.1 Java之父——高斯林
1.2 一次编译,到处运行
1.3 注释
2. 数据结构与变量
2.1 数据类型
2.2 变量
2.3 常量
3. 运算符
3.1 逻辑与 &&
3.2 逻辑 ||
3.3 逻辑非 !
3.4 特殊的位运算符(C语言没有)
4. 逻辑控制
4.1 选择(If 与 switch)
4.2 循环(while , for , do while)
4.3 输入输出
5. 方法
5.1 方法的定义
5.2 方法的传参
5.3 方法的重载
5.4 方法的递归
6. 数组
6.1 数组的定义方式
6.2 内存布局
6.3 数组的访问
6.4 数组指向null
6.5 常见的错误
6.6 数组作为参数进行传递
6.7 数组作为函数的返回值
6.8 数组常见的方法
6.9 二维数组
7. 类和对象
7.1 什么是类?如何定义类?
7.2 对象
7.3 this是什么?
7.4 构造方法
7.5 封装
7.6 static关键字
7.7 代码块
8. 继承和多态
8.1 继承
8.2 多态
9. 抽象类和接口
9.1 抽象类
9.2 接口
9.3 几个重要的接口
9.4 object类
9.5 面试问题: 抽类和接口的区别
10. String类
10.1 常用的方法
10.2 String ,StringBuffer ,StringBuilder的区别
11. 异常
11.1 程序自己抛出的异常
11.2 自定义的异常
11.3 异常的处理流程
Java是一门半编译型、半解释型语言。先通过javac编译程序把源文件进行编译,编译后生成的.class文件是由字节码组成的平台无关、面向JVM的文件。最后启动java虚拟机来运行.class文件,此时JVM会将字节码转换成平台能够理解的形式来运行。
Java中的注释主要分为以下三种:
1.单行注释:// 注释内容(用的最多)
2.多行注释:/* 注释内容*/(不推荐)
3.文档注释: /** 文档注释 */(常见于方法和类之上描述方法和类的作用),可以被javadoc工具解析,生成一套以网页文件形式体现的程序说明文档
注意:
1. 多行注释不能嵌套使用
2. 不论是单行还是多行注释,都不参与编译,即编译之后生成的.class文件中不包含注释信息。
在Java中数据类型主要分为两类:基本数据类型和引用数据类型。
基本数据类型有四类八种:
1. 四类:整型、浮点型、字符型以及布尔型
2. 八种:
注意:
1.不论是在16位系统还是32位系统,int都占用4个字节,long都占8个字节
2.整形和浮点型都是带有符号的
3.整型默认为int型,浮点型默认为double
4.字符串属于引用类型
什么是字节?
字节是计算机中表示空间大小的基本单位.
计算机使用二进制表示数据. 我们认为 8 个二进制位(bit) 为一个字节(Byte).
我们平时的计算机为 8GB 内存, 意思是 8G 个字节.
其中 1KB = 1024 Byte, 1MB = 1024 KB, 1GB = 1024 MB.
所以 8GB 相当于 80 多亿个字节
定义变量的语法格式为:
数据类型 变量名 = 初始值;
int的包装类型为 Integer
short的包装类型为Short
long的包装类型为Long
字节的包装类型为Byte
double的包装类型为Doublechar的包装类型为Character
boolean的包装类型为Boolean
final int a = 10;
语法规则:表达式1 && 表达式2,左右表达式必须是boolean类型的结果。
两个表达式都为真,结果才是真,只要有一个是假,结果就是假
语法规则:表达式1 || 表达式2,左右表达式必须是boolean类型的结果
左右表达式至少有一个为真,则结果为真
语法规则:! 表达式
真变假,假变真。
注意:
对于 && , 如果左侧表达式值为 false, 则表达式结果一定是 false, 无需计算右侧表达式.
对于 ||, 如果左侧表达式值为 true, 则表达式结果一定是 true, 无需计算右侧表达式.
& 和 | 如果表达式结果为 boolean 时, 也表示逻辑运算. 但与 && || 相比, 它们不支持短路求值
无符号右移 >>>: 最右侧位不要了, 最左侧补 0.
if 语句:条件必须是boolan类型的
不能做switch参数的数据类型:float double boolean long
while循环条件为 true, 则执行循环语句; 否则结束循环.
for语句: 表达式1: 用于初始化循环变量初始值设置,在循环最开始时执行,且只执行一次
表达式2: 循环条件,满则循环继续,否则循环结束
表达式3: 循环变量更新方式
for(表达式①;布尔表达式②;表达式③){
表达式④;
}
do while语句:先执行循环语句, 再判定循环条件,循环条件成立则继续执行,否则循环结束
注意:
1. do while 循环最后的分号不要忘记
2. 一般 do while 很少用到, 更推荐使用 for 和 while.
while (sc.hasNextlnt0) {
输入输出
int tmp = sc.nextlnt0();
sum += tmp;
num++;
}
循环输出/多组输入:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) { // 循环读入多组数据
int a = scanner.nextInt();
int b = scanner.nextInt();
System.out.println(a + b);
}
scanner.close();
}
}
// 方法定义
修饰符 返回值类型 方法名称([参数类型 形参 ...]){
方法体代码;
[return 返回值];
}
public static funcl(int[] array) (
array = new int[10];
}
public static funcl(int[] array) (
array[l];
}
方法的返回值:返回一个数组
1. 方法名必须相同
2. 参数列表必须不同(参数的个数不同、参数的类型不同、类型的次序必须不同)
3. 与返回值类型是否相同无关
1.趋近于终止的条件
2.调用自己本身
3.找到递推公式
int[] array = {1,2,3,4};
int[] array = new int[]{1,2,3,4,5,6};
JVM的5块内存:虚拟机栈,本地方法栈、方法区、堆、程序计数器
数组的长度可以用 数组名 .length 的方式得到
然后利用for循环遍历数组下标即可完成数组的访问
null 在 Java 中表示 "空引用" , 也就是一个不指向对象的引用.
null 的作用类似于 C 语言中的 NULL (空指针), 都是表示一个无效的内存位置. 因此不能对这个内存进行任何读写操作. 一旦尝试读写, 就会抛出 NullPointerException.
1.数组越界异常
int[] array = {1, 2, 3};
System.out.println(array[3]); // 数组中只有3个元素,下标一次为:0 1 2,array[3]下标越界
// 执行结果
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 100
at Test.main(Test.java:4)
2. 空针异常
int[] arr = null;
System.out.println(arr[0]);
// 执行结果
Exception in thread "main" java.lang.NullPointerException
at Test.main(Test.java:6)
1. 参数传基本数据类型
public static void main(String[] args) {
int num = 0;
func(num);
System.out.println("num = " + num);
}
public static void func(int x) {
x = 10;
System.out.println("x = " + x);
}
// 执行结果
x = 10
num = 0
在func方法中修改形参 x 的值, 不影响实参的 num 值.
2. 参数传数组类型(引用数据类型)
public static void main(String[] args) {
int[] arr = {1, 2, 3};
func(arr);
System.out.println("arr[0] = " + arr[0]);
}
public static void func(int[] a) {
a[0] = 10;
System.out.println("a[0] = " + a[0]);
}
// 执行结果
a[0] = 10
arr[0] = 10
发现在func方法内部修改数组的内容, 方法外部的数组内容也发生改变.
因为数组是引用类型,按照引用类型来进行传递,是可以修改其中存放的内容的
例子: 获取斐波那契数列的前N项
public class TestArray {
public static int[] fib(int n){
if(n <= 0){
return null;
}
int[] array = new int[n];
array[0] = array[1] = 1;
for(int i = 2; i < n; ++i){
array[i] = array[i-1] + array[i-2];
}
return array;
}
public static void main(String[] args) {
int[] array = fib(10);
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
数组的拷贝:
import java.util.Arrays;
public static void func(){
// newArr和arr引用的是同一个数组
// 因此newArr修改空间中内容之后,arr也可以看到修改的结果
int[] arr = {1,2,3,4,5,6};
int[] newArr = arr;
newArr[0] = 10;
System.out.println("newArr: " + Arrays.toString(arr));
// 使用Arrays中copyOf方法完成数组的拷贝:
// copyOf方法在进行数组拷贝时,创建了一个新的数组
// arr和newArr引用的不是同一个数组
arr[0] = 1;
newArr = Arrays.copyOf(arr, arr.length);
System.out.println("newArr: " + Arrays.toString(newArr));
// 因为arr修改其引用数组中内容时,对newArr没有任何影响
arr[0] = 10;
System.out.println("arr: " + Arrays.toString(arr));
System.out.println("newArr: " + Arrays.toString(newArr));
// 拷贝某个范围.
int[] newArr2 = Arrays.copyOfRange(arr, 2, 4);
System.out.println("newArr2: " + Arrays.toString(newArr2))
}
数组的排序:
顺序查找、二分查找、冒泡排序,冒泡排序的效率低,可以用Java内置的方法:Arrays.sort()
public static void main(String[] args) {
int[] arr = {9, 5, 2, 7};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
}
Java中 列可以省略,行不可以省略(与C语言相反)
类是用来描述对象的
// 创建类
class ClassName{
field; // 字段(属性) 或者 成员变量
method; // 行为 或者 成员方法
}
类中包含:
字段/属性/成员变量:如果是普通的成员变量,需要通过对象的引用来访问,如果是静态的成员变量,需要类名来访问。
方法/成员方法:
如果是普通的成员方法,需要通过对象的引用来访问,如果是静态的成员方法,需要类名来访问。
1.对象是通过new 关键字来进行实例化的,可以实例化多个对象
2.对象当中有,定义好的普通的成员变量。可以通过对象的引用 来访问对象中的成员变量
this:当前对象的引用。
可以通过this:
1.访问自己的成员变量
2.访问自己的成员方法
3.调用自己的构造方法
谁调用这个方法,谁就是this
方法名和类名一样,没有返回值。可以有多个,也意味着构造方法是可以发生重载的。
1.构造方法是什么时候被调用的呢?实例化对象的同时被调用.
2.如果一个类没有提供任何的构造方法,默认会有一个不带参数的构造方法。
3.但是如果我么能实现了任何一个构造方法,那么此时就不会再提供任何一个构造方法了
4.this在构造方法当中调用其他的构造方法的时候,必须放到第一行
5.默认初始化:没有初始化时,有一个默认的值。引用类型默认为null,boolean类型默认为false
6.就地初始化,定义成员变量的时候,直接初始化
隐藏类内部的实现细节,通过公开的方法来操作这些数据,在实现上,是采用private修饰成员变量或者成员方法。体现了类的安全性
1.提供get和set方法来实现
2.访问修饰限定符的问题
3.包:组织类的
不依赖对象,通过类名进行访问的。定义的成员变量 是存在方法区的,只有1份,所有类共享
静态代码块:使用static定义的代码块。一般用于初始化静态成员变量。
构造代码块:也叫实例代码块。一般用于初始化实例成员变量。
局部代码块:也叫普通代码块。用于限定变量的生命周期 。
执行顺序:静态的[只执行1次]、实例、构造方法
继承是对共性的抽取,这样可以达到对代码的一个复用效果。看作:is - a的关系
定义:
A extends B
A:子 派生类
B:父类、基类、超类
成员访问:
1.同名的怎么访间?就近原则,子类用子类,子类无找父类,父类无就报错
2.如何指定访问父类的成员,通过super关键字
super关键
1.super访问父类的成员变量
2.super访问父类的成员方法
3.super访问父类的构造方法
当子类继承父类之后,要帮助父类的成员进行初始化。子类当中显示的调用父类的构造方法。
继承关系上的执行顺序:
父类的静态,子类的静态。
父类的实例,父类的构造。
子类的实例,子类的构造。
如果一个类不想被继承,那么就把这个类定义为final修饰。证明这个类 是不可以被继承的
Java不支持多继承!!!
组台表示对象之间是has-a的关系
多台:是一种思想,代码层次上实现
向上转型:父类用用子类对象
Animal animal = new Dog(); 狗是一个动物
重写:
1.方法名相同
2.形式参数列表相同(个数、数据类型、 顺序)
3.返回值也要相同
通过父类引用 来调用这个被重写的 方法,此时发生动态绑定
向下转型:不安全
Dog dog - animal; 因为不是所有的动物都是狗配合instanceof关键字一起使用,并且需要强制类型转换。
静态绑定,指的是在编译的时候进行的绑定,比如: 重载
抽象类:当这个类不能具体表达某个对象的时候,我们就把这个类定义为抽象类
包含抽象方法:被abstract修饰的,表示这个方法,没有具体的实现
包含抽象方法后,这个类必须也被abstract修饰
抽象类不能被实例化,存在构造方法。因为可以被子类继承后,调用这个构造方法初始化抽象类的成员
只能被继承,所以继承之后,需要重写抽象类兰中的抽象方法,除非当前这个子类是抽象类
抽象方法的特点,参考继承的重写
接口: 是被interface修饰的。
1.接口也是不可以被实例化的
2.类和接口的关系是implements A
3.一旦实现了某个接口,就得重写接口当中的所有的成员方法
接口当中的成员变量默认为:public static final
接口当中的成员方法默认为:public abstract
如果你什么都没有写,那么就是上述所默认的
接口和接口之间可以使用关键字extends。表示A接口扩展了B接口的功能
interface A extends B,C,D{}
抽象类 和 接口 都是可以发生向上转型的
1.Compareable
2.Comparator
这两个接口是比较大小的。
Compareable对类的侵入性更强Comparator 更灵活一点
3. Cloneable 深拷贝和浅拷贝的问题
object类是所有类的父类,包含一些重要的方法:
1.equals 他是比较是否相同的,返回值true false
2.默认是比较地址的
3.我们如果比较自定义类型的时候,建议重写这个方法
核心区别: 抽象类中可以包含普通方法和普通字段, 这样的普通方法和字段可以被子类直接使用(不必重写), 而接口中不能包含普通方法, 子类必须重写所有的抽象方法
length() //求数组的长度
isEmpty() //变量是否已经初始化
compareTolgnoreCase() //比较大小,忽视大小写
charAt() //返回对应位置上的字符
拼接的时候 建议使用后2个
StringBuilder是线程不安全的
StringBuffer是线程安全的,但是不涉及线程安全的情况下使用,可能会有效率的问题,频繁的加锁,释放锁,都会消耗系统的资源。
1. 可以自己处理异常
2. throws 声明异常
3. throw 抛出异常
4. try catch finally 处理异常
finally一定会被执行的
catch会获具体的异常
具体方式:
1. 自定义异常类,然后继承自Exception 或者 RunTimeException
2. 实现一个带有String类型参数的构造方法,参数含义:出现异常的原因
注意事项:
自定义异常通常会继承自 Exception 或者 RuntimeException
继承自 Exception 的异常默认是受查异常
继承自 RuntimeException 的异常默认是非受查异常
【异常处理流程总结】
1.程序先执行 try 中的代码
2.如果 try 中的代码出现异常, 就会结束 try 中的代码, 看和 catch 中的异常类型是否匹配.
3.如果找到匹配的异常类型, 就会执行 catch 中的代码
4.如果没有找到匹配的异常类型, 就会将异常向上传递到上层调用者.
5.无论是否找到匹配的异常类型, finally 中的代码都会被执行到(在该方法结束之前执行).
6.如果上层调用者也没有处理的了异常, 就继续向上传递.
7.一直到 main 方法也没有合适的代码处理异常, 就会交给 JVM 来进行处理, 此时程序就会异常终止.
( 注:图片来自网络,如有侵权,请联系删除 )
希望对大家有所帮助,感谢观看!!!