1.开发环境搭建
JDK = JRE+开发工具集(javac等编译工具)
JRE = JVM + java核心类库
Path环境变量: windows 操作系统 执行命令时需要搜寻的路径
为什么要配path环境变量?
希望java的开发工具在任何文件路径下都可以执行成功
开发流程:
java程序编写->编译->运行 的过程
编写: 我们编写的java代码 保存在 .java的源文件中
编译: 使用javac.exe 编译我们的 .java源文件 变成 .class的字节码文件
运行: 使用java.exe 运行我们的字节码文件
在一个java源文件中可以声明多个类(class) 但是只能有一个是 public的 且public的类名必须与源文件名相同
编译的后会生成一个或多个字节码文件 文件名与 源文件的类名相同.
main()方法
public void static main(String[] args){}
关键字
关键字都是小写的
自己可以取名的地方叫标识符
标识符规范
1. 26个字母大小写 , 0-9 , _ 或 $
2. 数字不可以开头
3. 不能用关键字 或保留字 但可以包含
4. 不能包含空格
5. 区分大小写
变量
byte (1字节) \ short(2字节) \ int(4字节) \ long(8字节)
float(4字节) \ double(8字节)
char(2字节)
变量声明的位置
分支循环
① 根据switch表达式中的值,依次匹配各个case中的常量。一旦匹配成功,则进入相应case结构中,调用其执行语句。
当调用完执行语句以后,则仍然继续向下执行其他case结构中的执行语句,直到遇到break关键字或此switch-case结构末尾结束为止。
② break,可以使用在switch-case结构中,表示一旦执行到此关键字,就跳出switch-case结构
③ switch结构中的表达式,只能是如下的6种数据类型之一:
byte 、short、char、int、枚举类型(JDK5.0新增)、String类型(JDK7.0新增)
④ case 之后只能声明常量。不能声明范围。
⑤ break关键字是可选的。
⑥ default:相当于if-else结构中的else. default结构是可选的,而且位置是灵活的。
3.如果switch-case结构中的多个case的执行语句相同,则可以考虑进行合并。
4.break在switch-case中是可选的
break 和 continue
break 结束循环
continue 结束本次循环
后面都不能加语句
Arrays常用工具
//1.boolean equals(int[] a,int[] b):判断两个数组是否相等。
int[] arr1 = new int[]{1,2,3,4};
int[] arr2 = new int[]{1,3,2,4};
boolean isEquals = Arrays.equals(arr1, arr2);
System.out.println(isEquals);
//2.String toString(int[] a):输出数组信息。
System.out.println(Arrays.toString(arr1));
//3.void fill(int[] a,int val):将指定值填充到数组之中。
Arrays.fill(arr1,10);
System.out.println(Arrays.toString(arr1));
//4.void sort(int[] a):对数组进行排序。
Arrays.sort(arr2);
System.out.println(Arrays.toString(arr2));
//5.int binarySearch(int[] a,int key)
int[] arr3 = new int[]{-98,-34,2,34,54,66,79,105,210,333};
int index = Arrays.binarySearch(arr3, 210);
if(index >= 0){
System.out.println(index);
}else{
System.out.println("未找到");
}
面向对象
强调的是具备功能的对象, 考虑谁来做
JVM
编译完源程序以后,生成一个或多个字节码文件。
我们使用JVM中的类的加载器和解释器对生成的字节码文件进行解释运行。意味着,需要将字节码文件对应的类加载到内存中,涉及到内存解析。
虚拟机栈,即为平时提到的栈结构。我们将局部变量存储在栈结构中
堆,我们将new出来的结构(比如:数组、对象)加载在对空间中。补充:对象的属性(非static的)加载在堆空间中。
方法区:类的加载信息、常量池、静态域
对比:属性 vs 局部变量
1.相同点:
* 1.1 定义变量的格式:数据类型 变量名 = 变量值
* 1.2 先声明,后使用
* 1.3 变量都其对应的作用域
2.不同点:
2.1 在类中声明的位置的不同
* 属性:直接定义在类的一对{}内
* 局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量
*
* 2.2 关于权限修饰符的不同
* 属性:可以在声明属性时,指明其权限,使用权限修饰符。
* 常用的权限修饰符:private、public、缺省、protected --->封装性
* 局部变量:不可以使用权限修饰符。
*
* 2.3 默认初始化值的情况:
* 属性:类的属性,根据其类型,都默认初始化值。
* 整型(byte、short、int、long:0)
* 浮点型(float、double:0.0)
* 字符型(char:0 (或'\u0000'))
* 布尔型(boolean:false)
*
* 引用数据类型(类、数组、接口:null)
*
* 局部变量:没默认初始化值。
* 意味着,我们在调用局部变量之前,一定要显式赋值。
* 特别地:形参在调用时,我们赋值即可。
*
* 2.4 在内存中加载的位置:
* 属性:加载到堆空间中 (非static)
* 局部变量:加载到栈空间
面试题:方法的重载与重写的区别?throws\throw
String\StringBuffer\StringBuilder
Collection\CollectionsCollection是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。实现该接口的类主要有List和Set,该接口的设计目标是为了各种具体的集合提供最大化的统一的操作方式。
Collections是针对集合类的一个包裹类,它提供了一系列静态方法实现对各种集合的搜索、排序以及线程安全化等操作,其中的大多数方法都是用于处理线性表。Collections类不能实例化,如同一个工具类,服务于Collection框架。如果在使用Collections类的方法时,对应的Collection对象null,则这些方法都会抛出NullPointerException。
final\finally\finalize
...抽象类、接口
sleep() / wait()
java值传递
如果变量是基本数据类型,此时赋值的是变量所保存的数据值。
如果变量是引用数据类型,此时赋值的是变量所保存的数据的地址值。
封装
为了低耦合(仅对外部暴露少量的方法用于引用)
把想隐藏的隐藏起来 想暴露的暴露出来
权限修饰符
属性的赋值顺序
* 总结:属性赋值的先后顺序
*
*
* ① 默认初始化
* ② 显式初始化
* ③ 构造器中初始化
* **********************
* ④ 通过"对象.方法" 或 "对象.属性"的方式,赋值
*
* 以上操作的先后顺序:① - ② - ③ - ④
this关键字
1.可以调用的结构:属性、方法;构造器
2.this调用属性、方法:
this理解为:当前对象 或 当前正在创建的对象2.1 在类的方法中,我们可以使用"this.属性"或"this.方法"的方式,调用当前对象属性或方法。但是,
* 通常情况下,我们都择省略"this."。特殊情况下,如果方法的形参和类的属性同名时,我们必须显式
* 的使用"this.变量"的方式,表明此变量是属性,而非形参。
*
* 2.2 在类的构造器中,我们可以使用"this.属性"或"this.方法"的方式,调用当前正在创建的对象属性或方法。但是,通常情况下,我们都择省略"this."。特殊情况下,如果构造器的形参和类的属性同名时,我们必须显式的使用"this.变量"的方式,表明此变量是属性,而非形参。3.this调用构造器:
① 我们在类的构造器中,可以显式的使用"this(形参列表)"方式,调用本类中指定的其他构造器
② 构造器中不能通过"this(形参列表)"方式调用自己
③ 如果一个类中有n个构造器,则最多有 n - 1构造器中使用了"this(形参列表)"
④ 规定:"this(形参列表)"必须声明在当前构造器的首行
⑤ 构造器内部,最多只能声明一个"this(形参列表)",用来调用其他的构造器
继承
创建子类的实例的时候
先创建父类实例,执行父类的构造方法
在创建子类实例,执行子类的构造方法
两个实例绑定 成为一个实例
调用成员
先调子类 子类没有找父类
方法的重写
子类不满意父类的方法 可重写
方法的声明: 权限修饰符 返回值类型 方法名(形参列表) throws 异常的类型{
* //方法体
* }
* 约定俗称:子类中的叫重写的方法,父类中的叫被重写的方法
* ① 子类重写的方法的方法名和形参列表与父类被重写的方法的方法名和形参列表相同
* ② 子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符
* >特殊情况:子类不能重写父类中声明为private权限的方法
* ③ 返回值类型:
* >父类被重写的方法的返回值类型是void,则子类重写的方法的返回值类型只能是void
* >父类被重写的方法的返回值类型是A类型,则子类重写的方法的返回值类型可以是A类或A类的子类
* >父类被重写的方法的返回值类型是基本数据类型(比如:double),则子类重写的方法的返回值类型必须是相同的基本数据类型(必须也是double)
* ④ 子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型(具体放到异常处理时候讲)
* **********************************************************************
* 子类和父类中的同名同参数的方法要么都声明为非static的(考虑重写,要么都声明为static的(不是重写)。
5.面试题:
区分方法的重写和重载?
答:
① 二者的概念:
② 重载和重写的具体规则
③ 重载:不表现为多态性。
重写:表现为多态性。
重载,是指允许存在多个同名方法,而这些方法的参数不同。编译器根据方法不同的参数表,对同名方法的名称做修饰。对于编译器而言,这些同名方法就成了不同的方法。它们的调用地址在编译期就绑定了。Java的重载是可以包括父类和子类的,即子类可以重载父类的同名不同参数的方法。
所以:对于重载而言,在方法调用之前,编译器就已经确定了所要调用的方法,这称为“早绑定”或“静态绑定”;而对于多态,只等到方法调用的那一刻,解释运行器才会确定所要调用的具体方法,这称为“晚绑定”或“动态绑定”。
引用一句Bruce Eckel的话:“不要犯傻,如果它不是晚绑定,它就不是多态。”
super()默认调用父类的无惨构造
super.f() 一般在方法重写时,调用父类中的同一个方法
3.super调用属性、方法:
3.1 我们可以在子类的方法或构造器中。通过使用"super.属性"或"super.方法"的方式,显式的调用父类中声明的属性或方法。但是,通常情况下,我们习惯省略"super."
3.2 特殊情况:当子类和父类中定义了同名的属性时,我们要想在子类中调用父类中声明的属性,则必须显式的使用"super.属性"的方式,表明调用的是父类中声明的属性。
3.3 特殊情况:当子类重写了父类中的方法以后,我们想在子类的方法中调用父类中被重写的方法时,则必须显式的使用"super.方法"的方式,表明调用的是父类中被重写的方法。
多态
类型转换 : 向上转型(多态)和向下转型
前提 : 继承+重写
对象的多态性,只适用于方法,不适用于属性(编译和运行都看左边)
向下转型是 用 instanceof
a instanceof A:判断对象a是否是类A的实例。如果是,返回true;如果不是,返回false。
8.1 谈谈你对多态性的理解?
① 实现代码的通用性。
② Object类中定义的public boolean equals(Object obj){ }
JDBC:使用java程序操作(获取数据库连接、CRUD)数据库(MySQL、Oracle、DB2、SQL Server)
③ 抽象类、接口的使用肯定体现了多态性。(抽象类、接口不能实例化)
多态是运行时行为
final
修饰属性 修饰的属性为常量
修饰方法 方法不能被重写
修饰类 不能被继承
包装类
为了使基本数据类型的变量具有类的特征,引入包装类。
抽象类
abstract: 抽象的
1.可以用来修饰:类、方法
2.具体的:
abstract修饰类:抽象类
* > 此类不能实例化
* > 抽象类中一定有构造器,便于子类实例化时调用(涉及:子类对象实例化的全过程)
* > 开发中,都会提供抽象类的子类,让子类对象实例化,完成相关的操作 --->抽象的使用前提:继承性abstract修饰方法:抽象方法
* > 抽象方法只方法的声明,没方法体
* > 包含抽象方法的类,一定是一个抽象类。反之,抽象类中可以没有抽象方法的。
* > 若子类重写了父类中的所的抽象方法后,此子类方可实例化
* 若子类没重写父类中的所的抽象方法,则此子类也是一个抽象类,需要使用abstract修饰
3.注意点:
* 1.abstract不能用来修饰:属性、构造器等结构
* 2.abstract不能用来修饰私方法、静态方法、final的方法、final的类
接口
interface:接口
1.使用说明:
1.接口使用interface来定义
* 2.Java中,接口和类是并列的两个结构
* 3.如何定义接口:定义接口中的成员
*
* 3.1 JDK7及以前:只能定义全局常量和抽象方法
* >全局常量:public static final的.但是书写时,可以省略不写
* >抽象方法:public abstract的
*
* 3.2 JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法(略
*
* 4. 接口中不能定义构造器的!意味着接口不可以实例化
*
* 5. Java开发中,接口通过让类去实现(implements)的方式来使用.
* 如果实现类覆盖了接口中的所抽象方法,则此实现类就可以实例化
* 如果实现类没覆盖接口中所的抽象方法,则此实现类仍为一个抽象类
*
* 6. Java类可以实现多个接口 --->弥补了Java单继承性的局限性
* 格式:class AA extends BB implements CC,DD,EE
*
* 7. 接口与接口之间可以继承,而且可以多继承
*
* *******************************
* 8. 接口的具体使用,体现多态性
* 9. 接口,实际上可以看做是一种规范
4.Java8中关于接口的新规范
//知识点1:接口中定义的静态方法,只能通过接口来调用。//知识点2:通过实现类的对象,可以调用接口中的默认方法。
//如果实现类重写了接口中的默认方法,调用时,仍然调用的是重写以后的方法//知识点3:如果子类(或实现类)继承的父类和实现的接口中声明了同名同参数的默认方法,那么子类在没重写此方法的情况下,默认调用的是父类中的同名同参数的方法。-->类优先原则
//知识点4:如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法,
//那么在实现类没重写此方法的情况下,报错。-->接口冲突。
//这就需要我们必须在实现类中重写此方法
//知识点5:如何在子类(或实现类)的方法中调用父类、接口中被重写的方法
public void myMethod(){
method3();//调用自己定义的重写的方法
super.method3();//调用的是父类中声明的
//调用接口中的默认方法
CompareA.super.method3();
CompareB.super.method3();
}
接口和抽象类有什么区别?
相同点: 都不能被实例化 都可以包含抽象方法
不同点: 抽象类可以有构造器 方便子类调用 (单继承)
接口是多继承
类与接口是多实现的
内部类
内部类:类的第五个成员
1.定义:Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类.
2.内部类的分类:
成员内部类(静态、非静态 ) vs 局部内部类(方法内、代码块内、构造器内)
3.成员内部类的理解:
一方面,作为外部类的成员:
* >调用外部类的结构
* >可以被static修饰
* >可以被4种不同的权限修饰
*
另一方面,作为一个类:
* > 类内可以定义属性、方法、构造器等
* > 可以被final修饰,表示此类不能被继承。言外之意,不使用final,就可以被继承
* > 可以被abstract修饰
4.成员内部类:
4.1如何创建成员内部类的对象?(静态的,非静态的)
//创建静态的Dog内部类的实例(静态的成员内部类):
Person.Dog dog = new Person.Dog();//创建非静态的Bird内部类的实例(非静态的成员内部类):
//Person.Bird bird = new Person.Bird();//错误的
Person p = new Person();
Person.Bird bird = p.new Bird();
4.2如何在成员内部类中调用外部类的结构?
class Person{
String name = "小明";
public void eat(){
}
//非静态成员内部类
class Bird{
String name = "杜鹃";
public void display(String name){
System.out.println(name);//方法的形参
System.out.println(this.name);//内部类的属性
System.out.println(Person.this.name);//外部类的属性
//Person.this.eat();
}
}
}
5.局部内部类的使用:
//返回一个实现了Comparable接口的类的对象
public Comparable getComparable(){
//创建一个实现了Comparable接口的类:局部内部类
//方式一:
// class MyComparable implements Comparable{
//
// @Override
// public int compareTo(Object o) {
// return 0;
// }
//
// }
//
// return new MyComparable();
//方式二:
return new Comparable(){@Override
public int compareTo(Object o) {
return 0;
}
};
}注意点:
在局部内部类的方法中(比如:show如果调用局部内部类所声明的方法(比如:method)中的局部变量(比如:num)的话,要求此局部变量声明为final的。
*
jdk 7及之前版本:要求此局部变量显式的声明为final的
jdk 8及之后的版本:可以省略final的声明
总结:
成员内部类和局部内部类,在编译以后,都会生成字节码文件。
格式:成员内部类:外部类$内部类名.class
局部内部类:外部类$数字 内部类名.class
异常
* java.lang.Throwable
* |-----java.lang.Error:一般不编写针对性的代码进行处理。
* |-----java.lang.Exception:可以进行异常的处理
* |------编译时异常(checked)
* |-----IOException
* |-----FileNotFoundException
* |-----ClassNotFoundException
* |------运行时异常(unchecked,RuntimeException)
* |-----NullPointerException
* |-----ArrayIndexOutOfBoundsException
* |-----ClassCastException
* |-----NumberFormatException
* |-----InputMismatchException
* |-----ArithmeticException