JDK:
Java标准开发包,它提供了编译、运⾏Java程序所需的各种⼯具和资源,包括Java编译器、Java运⾏时环境,以及常⽤的Java类库等。
JRE:
Java运⾏环境,⽤于解释执⾏Java的字节码⽂件。
JVM
Java虚拟机,是JRE的⼀部分。负责解释执⾏字节码⽂件,是可运⾏java字节码⽂件的虚拟计算机
区别联系:
JDk包含JRE,JDK 和 JRE 中都包含 JVM。JDK出了包含jre还包含⼀些常⽤开发⼯具和基础类库
JDK ⽤于开发
JRE ⽤于运⾏java程序
JVM 是 java 编程语⾔的核⼼并且具有平台独⽴性。
4种基本控制结构:
顺序结构、选择结构、循环结构、异常处理逻辑结构
权限修饰符返回值声明方法名称(参数列表){
方法中封装的逻辑功能:
return返回值:
}
// /* */ /** **/
注意事项
由字⺟、数字、下划线(_)和美元符号($)组成。
不能以数字开头。
不能是Java中的关键字。
基本数据类型变量 引⽤数据类型变量
局部变量:⽅法或语句块内部定义的变量
成员变量:⽅法外部、类的内部定义的变量
boolean 类型不能转换成任何其它数据类型。
⾃动类型转换:容量⼩的类型⾃动转换成容量⼤的数据类型 byte,short,int -> float ->long->double
byte,short,int 不会互相转换,它们三者在计算时会转换成 int 类型
强制类型转换:容量⼤的类型转换成容量⼩的数据类型时,要加上强制转换符()
1)成员变量(全局级变量 private int i=0;或静态变量 private static String name="lisi")
在类体内定义的变量称为成员变量,它的作⽤域是整个类
2)局部变量
在⼀个⽅法或⽅法内代码块中定义的变量称为局部变量
java中的常量:final
float a=133.3f; 带上f
long a= 22222020202l; 带上l
char c='6'; 带上 ' '
if
else if
else
switch(XX) { //java特有 枚举 short byte C语⾔:字符,int
case 1 : XX ;break;
case 2: XX ;break;
default(可有可⽆): XX break;
}
while
for
do while
for each
int [] a = new int [10];
//for循环遍历
for ( int i=0 ; i<10 ; i++ )
a[i];
//for-each循环遍历
for ( int k : a);
1
int[][] arr = new int[3][];
arr[0]=new int[3];
2
int [][] arr2=new int[3][2];
arr[0][0]=33;
int arr4[][] = new int[][]{{1, 2, 3}, {2, 3}};
//声明数组;
int arr[]
//数组初始化;
int [] arr={1,2,3,4}
int [] arr=new int[]{1,2,3,4}
//查看数组⻓度;
arr.length;
//for each循环;
for(int a:arr){
System.out.println(a);
}
//数组拷⻉;
int [] arr2=arr1;
int[] arr2=Arrays.copyOf(arr,arr.length(⾃定义⻓度));
//数组排序;
Arrays.sort(arr);
//将int数组转换为字符串;
Arrays.toString(arr);
import java.util.Scanner;
输⼊
Scanner s=new Scanner(System.in);
s.nextInt()
s.nextLine()
s.nextFloat()
scanner.next()
输出
System.out.println("XX")
“通过 private、default 、protected、 public 关键字实现属性或⽅法的封装, 仅对外提供公共访问⽅式。+
“⾼内聚,低耦合”4
封装的好处?
实现数据项和⽅法的隐藏
实现隐藏隔离,允许外部对类做有限的访问,开发者可以⾃由的改变类的内部实现
提⾼了代码的重⽤性
通过 extends
。
两个好处: +
代码重⽤了
通过继承 实现对现实世界更加准确的建模+
⼀个对象变量可以指向多种实际类型对象的现象被称为“多态”
三个必要条件:继承、⽅法的重写、⽗类引用指向⼦类对象
多态的好处:
Java中多态的实现⽅式:
接⼝实现
继承⽗类进⾏⽅法重写
同一个类中进⾏⽅法重载
⽗类引用指向⼦类对象
–实例化(对象的创建)
//通过 new 关键字创建
//⽐如
Student XieYUhui = new Student();
XieYUhui.setAge=20;
class Student{
private int age;
public static void setAge(int age){
this.age=age;
}
}
--------------------------------------------------
class Stu{
//1 属性设为私有
private int age;
//2 ⽅法 get set 你⾃⼰定义的
public void setAge(int age) {
this.age =age;
}
public int getAge() {
return this.age;
}
//我⾃⼰定义的⽅法
public void myPrint() {
System.out.println("nihao");
}
//3 构造函数
public Stu() {
}
public Stu(int age) {
this.age=age;
}
}
–类的定义(格式,注意事项)
[修饰符] class 类名 [extends ⽗类名] [implements 接⼝名]{
// 类体,包括类的成员变量和成员⽅法
}
Object类是所有类的⽗类,⾥⾯有很多⽅法
clone getClass toString equals hashCode notify notifyAll wait finalize
/*
1.getClass⽅法
获取运⾏时类型,返回值为Class对象
2.hashCode⽅法
返回该对象的哈希码值,是为了提⾼哈希表的性能(HashTable)
3.equals⽅法
判断两个对象是否相等,在Object源码中equals就是使⽤==去判断,所以在Object中equals是等价于
==的,但是在String及某些类对equals进⾏了重写,实现不同的⽐较。
4.clone⽅法
此⽅法只实现了⼀个浅层拷⻉,对于基本类型字段成功拷⻉,但是如果是嵌套对象,只做了赋值,也就是只把
地址拷⻉了,所以没有成功拷⻉,需要⾃⼰重写clone⽅法进⾏深度拷⻉。
5.toString⽅法
返回⼀个String字符串,⽤于描述当前对象的信息,可以重写返回对⾃⼰有⽤的信息,默认返回的是当前对
象的类名+hashCode的16进制数字。
6.wait⽅法
多线程时⽤到的⽅法,作⽤是让当前线程进⼊等待状态,同时也会让当前线程释放它所持有的锁。直到其他
线程调⽤此对象的 notify() ⽅法或 notifyAll() ⽅法,当前线程被唤醒
7.notify⽅法
多线程时⽤到的⽅法,唤醒该对象等待的某个线程
8.notifyAll⽅法
多线程时⽤到的⽅法,唤醒该对象等待的所有线程
9.finalize
对象在被GC释放之前⼀定会调⽤finalize⽅法,对象被释放前最后的挣扎,因为⽆法确定该⽅法什么时候
被调⽤,很少使⽤
*/
class ⽗类 {
}
class ⼦类 extends ⽗类 {
}
public class Animal {
public String name;
private int id;
public Animal(String myName, String myid) {
//初始化属性值
}
public void eat() { }
public void sleep() { }
}
public class Penguin extends Animal{
}
/**
* @date 2023/6/29
*/
class Animal2{
public String name;
private int id;
public Animal2(String name,int myid) {
this.name=name;
id=myid;
}
public Animal2(String name) {
this.name=name;
}
public Animal2(int id2) {
id=id2;
}
public void eat() {
System.out.println("我是⽗类2我再吃饭");
}
}
public class Person2 extends Animal2 {
public Person2(int id2) {
super(id2);
}
public void eat() {
System.out.println("我是⼦类2,我在吃饭"); //重写⽗类的⽅法
}
public static void main(String[] args) {
Person2 p = new Person2(3);
p.eat();
}
}
//运行结果:我是⼦类2,我在吃饭
将类的某些信息隐藏在类的内部,不允许外部程序直接访问,⽽是通过该类提供getter setter的⽅法来对隐藏的信息进⾏操作和访问
3、封装的实现步骤
(1)修改属性的可⻅性设为(private)
(2)创建getter/setter⽅法(⽤于属性的读写)(通过这两种⽅法对数据进⾏获取和设定,对象通过
调⽤这两种发⽅法实现对数据的读写)
(3)在getter/setter⽅法中加⼊属性控制语句(对属性值的合法性进⾏判断
public class Person{
private String name;
private int age;
•
public int getAge(){
return age;
}
•
public String getName(){
return name;
}
•
public void setAge(int age){
this.age = age;
}
•
public void setName(String name){
this.name = name;
}
}
主要⽤来在创建对象时初始化对象, 即为对象成员变量赋初始值,
总与new运算符⼀起使⽤在创建对象的语句中.⼀个类可以有多个构造函数 ,
可根据其参数个数的不同或参数类型的不同来区分它们,即构造函数的重载。
必须载同⼀个类中
⽅法名相同
⽅法的参数的个数、顺序或类型不同
与⽅法的修饰符和或返回值没有关系
⽅法重写的注意事项:
1.重写的⽅法必须要和⽗类⼀模⼀样(包括返回值类型,⽅法名,参数列表)
2.重写的⽅法可以使⽤@Override注解来标识
3.⼦类中重写的⽅法的访问权限不能低于⽗类中⽅法的访问权限
权限修饰符 :
private < 默认(什么都不写) < protected < public
⽅法的重载:
在同⼀个类中,出现多个同名的⽅法,参数列表不同,与返回值类型,修饰⽆关
⽅法的重写:
⼦类中出现和⽗类中⼀模⼀样的⽅法(包括返回值类型,⽅法名,参数列表)
Java中为解决变量的命名冲突和不确定性问题,引⼊关键字this代表其所在⽅法的当前对象的引⽤:
1) 构造⽅法中指该构造器所创建的新对象;
public class B{
A a; //A是⼀个类
public B(A a){
this.a = a;
}
}
2) ⽅法中指调⽤该⽅法的对象;
public class Baby{
public void wakeUp(){
System.out.println("宝宝醒啦");
}
public void eat(){
this.wakeUp();
System.out.println("吃东⻄");
}
}
3) 在类本身的⽅法或构造器中引⽤该类的实例变量(全局变量)和⽅法
public void setName(String name){
this.name=name
}
this只能在类中的⾮静态⽅法中使⽤,静态⽅法和静态的代码块中绝对不能出现this
原因:static⽅法在类加载时就已经存在了,但是对象是在创建时才在内存中⽣成。
⼀句话概括:
1 super关键字主要存在于⼦类⽅法中,⽤于指向⼦类对象中的⽗类对象;可以访问⽗类的属性、函数以及构造函数。
2 ⼦⽗类存在着同名的成员(包括变量和⽅法)时,在⼦类中默认是访问⼦类的成员,可以通过super关键
字指定访问⽗类的成员;
3 默认会先调⽤⽗类⽆参的构造⽅法,可以通过super关键字指定调⽤⽗类的构造⽅法。
静态变量
private static String s1 = "static";
静态方法
public static void print2(){
System.out.println(str1);
System.out.println(str2);
print1();
}
静态代码块
static {
static int a=3;
}
1、被static修饰的变量属于类变量,可以通过类名.变量名直接引⽤,⽽不需要new出⼀个类来
2、被static修饰的⽅法属于类⽅法,可以通过类名.⽅法名直接引⽤,⽽不需要new出⼀个类来
–修饰类
final修饰的类,不能被继承(
–修饰⽅法
Final修饰的⽅法 不能被重写,但是⼦类可以⽤⽗类中final修饰的⽅法;
–修饰变量
1 基本类型变量使⽤final修饰了就不可变了
2 对于引⽤类型变量被final修饰了:引⽤变量引⽤不可变,但是引⽤对象的内容可以改变。
public class Test3 {
public static void main(String[] args) {
A a=new A();
a.a=3;
a.a=4;
}
}
final class A {
public int a=3;
}
(1)代表的事物不同
super代表的是⽗类空间的引⽤
this代表的是所属函数的调⽤者对象
(2)使⽤前提不同
super必须要有继承关系才能使⽤
this不需要继承关系也能使⽤
(3)调⽤的构造函数不同
super:调⽤⽗类的构造函数
this:调⽤所属类的构造函数
public abstract class Action {
public abstract void doSomething(); //抽象⽅法
public void test(){
};
}
普通变量 公共静态变量
普通⽅法 抽象⽅法
public interface UserService {
//接⼝中的所有定义的⽅法中其实都是抽象的 public abstract
//变量只能为 public static final 类型的
//public abstract void add();
//等效于 void add();
//int age = 99; 等效于
//public static final int age = 99;
int age = 99;
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
如下链接:
多态
成员内部类是最普通的内部类,它的定义为位于另⼀个类的内部,形如下⾯的形式:
class Circle {
double radius = 0;
public Circle(double radius) {
this.radius = radius;
}
class Draw { //内部类
public void drawSahpe() {
System.out.println("drawshape");
}
}
}
class Shape {
void draw() {}
}
class Circle extends Shape {
void draw() {
System.out.println("Circle.draw()");
}
}
//-----------------------------------------------------------------------
//成员内部类可以⽆条件访问外部类的所有成员属性和成员⽅法(包括private成员和静态成员)。
class Circle {
private double radius = 0;
public static int count =1;
public Circle(double radius) {
this.radius = radius;
}
class Draw { //内部类
public void drawSahpe() {
System.out.println(radius); //外部类的private成员
System.out.println(count); //外部类的静态成员
}
}
}
//-----------------------------------------------------------------------
//虽然成员内部类可以⽆条件地访问外部类的成员,⽽外部类想访问成员内部类的成员却不是这么随⼼所欲了。在外部类中如果要访问成员内部类的成员,必须先创建⼀个成员内部类的对象,再通过指向这个对象的引⽤来访问:
class Circle {
private double radius = 0;
public Circle(double radius) {
this.radius = radius;
Draw draw=new Draw();
draw.drawSahpe(); //必须先创建成员内部类的对象,再进⾏访问
}
class Draw { //内部类
public void drawSahpe() {
System.out.println(radius); //外部类的private成员
}
}
}
//创建格式
Outter outter = new Outter();
Outter.Inner inner = outter.new Inner(); //必须通过Outter对象来创建
class People {
public People() {
}
}
class Man{
public Man(){
}
public People getWoman() {
class Woman extends People{ //局部内部类(在⽅法⾥⾯)
int age =0;
}
return new Woman();
}
}
这点和类的静态成员属性有点类似,并且它不能使⽤外部类的⾮static成员变量或者⽅法
class Outter {
public Outter() {
}
static class Inner {
public Inner() {
}
}
}
⼀般编写事件监听的代码时都会使⽤ 这个
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//点击后执⾏的内容
}
});
异常的分类:Java中异常分为两类,一类是运行时异常,另一类是非运行时异常。
运行时异常可以在代码编写时不用显式地处理,因为Java虚拟机会自动进行处理。而非运行时异常则必须在代码中进行显式的处理,否则会导致程序的终止。
运行时异常 运行时异常是指那些可能在代码执行期间发生的异常,如数组越界、空指针引用等。这些异常不需要程序员在代码中显式地进行处理,因为Java虚拟机会自动进行处理。
非运行时异常 非运行时异常是指那些不是在代码执行期间发生的异常,如IOException、SQLException等。这些异常必须在代码中进行显式的处理,否则会导致程序的终止。
try、catch、finally。
try块中包含可能会出现异常的代码
catch块中处理异常
finally块中释放资源。
try{ //可能会出现异常的代码 }catch(Exception e){ //处理异常的代码 }
try代码块包含可能会抛出异常的代码,当异常发生时,程序会跳转到相应的catch代码块中,进行异常处理。
举个例子:
public class Review_exception {
public static void main(String[] args) {
method();
}
public static void method() {
int a = new Scanner(System.in).nextInt();
int b = new Scanner(System.in).nextInt();
System.out.println(a / b);
}
}
(上图中定义了一个静态方法 method(),其中通过 Scanner 类从标准输入读取两个整数 a 和 b,然后将它们相除的结果输出到标准输出。)
我们先搞出一个异常看看。
2/0 将0作为除数
抛出 java.lang.ArithmeticException 异常(异常的名称/类型)
异常的原因 /by zero
异常的位置(java:12 java:5)可以帮助开发者快速定位问题所在。
public static void method(){
try {int a = new Scanner(System.in).nextInt();
int b = new Scanner(System.in).nextInt();
System.out.println(a / b);}
catch(ArithmeticException aaa){
System.out.println("除数不能为0");
}
}
}
再次提醒格式!
//try里面放出现异常的代码
//catch圆括号里放异常类型及名称
//catch花括号里面放你的处理方式
在这个修正后的代码中,我们将method()方法中的try-catch语句进行了修正。try代码块中包含需要捕获异常的代码,即通过Scanner类从标准输入读取两个整数,然后进行除法运算。如果运算过程中出现除数为零的情况,就会抛出ArithmeticException异常,此时程序会跳转到catch代码块中,输出一条提示信息。
如果我们觉得异常的类型也太多了,就可以用所有异常类的超类Exception,
因此使用Exception作为catch块的参数可以处理所有可能出现的异常。这也是多态的一个应用,即在catch块中不关心子类的类型,只要是Exception异常都可以被接收和处理。
public static void method(){
try {int a = new Scanner(System.in).nextInt();
int b = new Scanner(System.in).nextInt();
System.out.println(a / b);}
catch(Exception aaa){
System.out.println("除数不能为0");
}
}
Java中的Throwable类提供了一个printStackTrace()方法,可以打印出异常的完整堆栈信息,包括异常的类型、消息、异常出现的位置以及异常发生时调用栈的信息。这个方法会在控制台输出异常的完整信息,便于我们查看异常的类型和异常发生时的调用栈,从而更好地定位和解决问题。
public static void method(){
try {int a = new Scanner(System.in).nextInt();
int b = new Scanner(System.in).nextInt();
System.out.println(a / b);}
catch(Exception aaa){
System.out.println("除数不能为0");
aaa.printStackTrace();
}
}
如图,在控制台输出了异常的完整信息!
在Java中,finally语句块用于定义一段无论是否发生异常都需要执行的代码。通常,我们将需要在程序结束前进行清理工作的代码放在finally语句块中,以确保这些代码在任何情况下都会被执行。
public static void method(){
try {int a = new Scanner(System.in).nextInt();
int b = new Scanner(System.in).nextInt();
System.out.println(a / b);
}
catch(Exception aaa){
System.out.println("除数不能为0");
}finally{
System.out.println("释放资源");
}
}
finally语句块的执行流程如下:
如果try语句块中发生了异常,Java虚拟机会跳过try语句块中的剩余代码,转而执行finally语句块中的代码。这可以用于进行资源的释放、清理等工作,以确保程序的正确性。
如果try语句块中没有发生异常,Java虚拟机也会执行finally语句块中的代码。这是因为finally语句块中的代码可能会包含一些必要的操作,比如关闭文件、释放资源等。
finally块中的代码会在try块中的代码执行完毕后无论是否抛出异常都会被执行。如果finally块在catch块之前,当try块中的代码抛出异常时,程序就会直接跳转到finally块中执行,而不是执行catch块中的代码。这样会导致catch块中的代码无法执行,无法对异常进行处理。
总之流程就是:
try失败了,马上转移到catch块,catch块完成后进行finally块。
try成功了,跳过catch块,直接进行finally块
如果try块和catch块有return指令,finally还是会执行。
总之,finally语句块是用来执行一些必须要做的操作,无论是否出现异常,都会被执行。因此,finally语句块通常被用来进行资源的释放、清理等操作,以保证程序的正确性和可靠性。
在Java中,抛出异常通常用于表示程序运行时出现的异常情况,例如参数错误、文件不存在、网络连接失败等等。如果程序遇到这些异常情况,可以通过抛出异常来通知调用者,让调用者进行相应的处理。
具体格式:
public class Review_exception {
public static void main(String[] args) throws Exception {
method2();
}
public static void method2() throws Exception{
int a = new Scanner(System.in).nextInt();//异常代码
int b = new Scanner(System.in).nextInt();//异常代码
System.out.println(a / b);//异常代码
}
}
常用库
多线程 略多
多线程
JDBC