java

138 阅读32分钟

image.png 类名要和文件名保持一致

public class ht {
    public static void main(String[] args){
        System.out.println("Hello World");
    }
}

C:\Users\zhangjinzhong\Desktop\java>javac ht.java 
C:\Users\zhangjinzhong\Desktop\java>java ht
 

数据类型

Java 提供了八种原始数据类型:

  • 数值型:byte、short、int、long、float、double
  • 字符型:char
  • 布尔型:boolean
基本数据类型
数值型:
    整型:byteshortintlong
    浮点型:floatdouble
字符型:char
布尔型:boolean
引用数据类型(内存操作)
数组、类、接口

image.png

但是对于以上给出的基本数据类型的定义,如果从实际的开发角度上,以下的几种类型最为常用:

· int型:只要是看见了整型的定义,其类型都是int;

· double型:只要是看见了小数的定义,其类型都是double;

· byte型:日后进行数据传输的时候使用此类型,讲解到IO,和编码转换的操作上使用;

· boolean:用于程序的逻辑操作使用;

· long:表示日期时间、表示文件长度的时候。

int age = 30;
double salary = 5000.50;
boolean isEmployed = true;
引用数据类型

包括类、接口、数组和枚举等。引用类型的变量存储对象的内存地址。

String name = "Alice";
int[] numbers = {1, 2, 3, 4, 5};

数组

初始化

// 直接初始化
int[] numbers = {1, 2, 3, 4, 5}; // 定义并初始化数组
 
// 定义后赋值
int[] moreNumbers = new int[5]; // 创建一个长度为5的数组
moreNumbers[0] = 10; // 赋值
moreNumbers[1] = 20;
moreNumbers[2] = 30;
moreNumbers[3] = 40;
moreNumbers[4] = 50;

 // 访问数组元素
 int firstNumber = numbers[0]; // 获取第一个元素

数组排序

import java.util.Arrays; // 导入Arrays类
 
public static void main(String[] args) {
    int[] numbers = {5, 2, 8, 1, 3}; // 初始化数组
    Arrays.sort(numbers); // 对数组进行排序
    System.out.println(Arrays.toString(numbers)); // 打印排序后的数组
}

数组复制

int[] original = {1, 2, 3, 4, 5};
int[] copy = Arrays.copyOf(original, original.length); // 复制数组 复制的数组,复制几位
System.out.println(Arrays.toString(copy)); // 输出复制的数组

多维数组

// 定义一个二维数组
int[][] matrix = new int[3][4]; // 3行4列的二维数组
 
// 初始化一个二维数组
int[][] matrix2 = {
    {1, 2, 3, 4},
    {5, 6, 7, 8},
    {9, 10, 11, 12}
};
//访问
int value = matrix2[1][2]; // 获取第二行第三列的元素
System.out.println(value); // 输出: 7
//遍历
for (int i = 0; i < matrix2.length; i++) { // 外层循环遍历每一行
    for (int j = 0; j < matrix2[i].length; j++) { // 内层循环遍历当前行的每一列
        System.out.print(matrix2[i][j] + " "); // 打印当前元素
    }
    System.out.println(); // 在每行结束后换行
}

数组的优缺点 1 优点

存储相同类型的数据:数组允许我们将相同类型的数据存储在一起。

快速访问:通过索引,可以快速访问和修改数组中的元素。

内存连续性:数组在内存中是连续存储的,访问速度较快。

2 缺点

固定大小:一旦定义,数组的大小就无法更改。

内存浪费:如果数组分配的大小大于实际使用的元素数量,会导致内存浪费。

操作不便:插入和删除元素的效率较低,尤其是在大数组中。

定义变量(标识符)或方法的时候也有一个明确的要求:第一个单词的首字母小写,之后每个单词的首字母大写,例如:studentName。而在定义类名称的时候(标识符),每一个单词的首字母大写,例如:TestDemo

switch

// 猜拳游戏: 1-石头,2-剪刀,3-布
int i = 1;
String str;
switch (i) {
    case 1:
        str = "石头";
        break;
    case 2:
        str = "剪刀";
        break;
    case 3:
        str = "布";
        break;
    default:
        str = "其他";
        break;
}
 
System.out.println("你出的是:" + str);
 
// 简写
String str = switch (i) {
    case 1 -> "石头";
    case 2 -> "剪刀";
    case 3 -> "布";
    default -> "其他";
};

循环

  1. 知道具体的循环次数,优先使用for循环

  2. while是先判断循环条件,在执行循环体

  3. do...while是执行一次的循环体,在判断循环条件

  4. do...while至少会执行一次

        while循环

int i = 1;
while (i <= 20) {
    System.out.println("好好学习天天向上,第" + i + "遍");
    i++;
}
 

// 打印1-10
int i = 0;          // 变量初始化
while (i < 10) {    // 循环条件
    i++;            // 变量改变
    System.out.println(i);
}

do...while 循环

Scanner scanner = new Scanner(System.in);
String res;
do {
    System.out.println("学习了java");
    System.out.println("请老师检查是否合格:");
    res = scanner.next();

}while ("n".equals(res)); 
System.out.println("今日学习圆满!");
 

// 打印1-10
int i = 0;          // 变量初始化
do {
    i++;            // 变量改变
    System.out.println("do...while 循环打印:" + i);
}while (i < 10);    // 循环条件

** for 循环**

 
Scanner scanner = new Scanner(System.in);
System.out.print("请输入一个值:");
int num = scanner.nextInt();
for (int i = 0, j = num; i <= num; i++, j--) {
    System.out.println(i + "+" + j + "=" + num);

} 


//**循环输入某同学期末考试的5门课成绩,并计算平均分。**
Scanner scanner = new Scanner(System.in);

System.out.println("请输入考评者的名字:");
String name = scanner.next();

int sum = 0;
for (int i = 1; i <= 5; i++) {
    System.out.println("请输入第" + i + "门功课的成绩:");
    int grade = scanner.nextInt();
    sum += grade;
}
int avaGrade = sum / 5;
System.out.println(name + "平均成绩是:" + avaGrade);
 


// 打印1-10
for (int i = 1; i <= 10; i++) {
    System.out.println("for 循环打印:" + i);
}
  • while 循环:先判断再执行

  • do-while 循环:先执行再判断。初始情况不满足循环条件时,do-while 至少也会执行一次。

  • for 循环:先判断再执行

项目 模块 包 类

  • 项目(Project):
    项目是最大的组织单位,通常代表一个完整的软件应用或一组相关的应用。一个项目可以包含多个模块,这些模块可能属于同一个应用的不同部分,或者构成一个应用的不同功能。

  • 模块(Module):
    模块是项目中的一个独立部分,它有自己的编译和运行属性。在Java中,模块的概念从Java 9开始引入,每一个模块都有自己的module-info.java文件来定义模块的属性和依赖。模块可以理解为一个独立的单元,有自己的作用域,可以包含多个包。

  • 包(Package):
    包是模块内部的划分,用于组织类和接口。它是类和接口的容器,提供了一种方式来命名和访问类。一个包中可以包含多个类和接口,它们通常具有相似的属性或功能。例如,所有的用户界面相关的类可以放在一个叫做com.example.ui的包中。

  • 类(Class):
    类是面向对象编程的基本单元,它包含对象的属性和行为。类可以继承其他类,实现接口,并可以包含抽象方法或具体方法。在Java中,每一个文件通常对应一个公开的类,这个类与文件名相同。

  • 接口(Interface):
    接口是一种完全抽象的类,它不能包含任何具体方法的实现,但是可以包含抽象方法。一个类可以实现多个接口,表明该类遵循接口中声明的抽象方法。接口定义了一种约定,规定了实现接口的类应遵循的规则。

  • bean:存放 JavaBean 类,通常被用来封装数据,如模型类。

  • dao:存放数据访问对象(Data Access Objects),这些类负责与数据库进行交互,执行增删改查等操作。

  • service:存放业务逻辑代码,处理业务流程。

  • controller:存放控制器类,负责处理 HTTP 请求,将请求转发到其他模块处理。

  • javabean 类:用来描述一类事物的类,eg: Student , Animal
  • 测试类: 用来检查其他类是否书写正确的,带有main 方法的类,是程序的入口
  • 工具类:不是用来描述一类事物的,而是帮我们做一些事情的类
   类名见名之意
   私有化构造方法,不让创建它的对象
   方法定义为静态
public class ArrUtil { 
    private ArrUtil(){}
    public static int getMax(){  return 1;};
    public static int getMin(){ return 1;};
    public static int getMum(){ return 1;};
    public static int getAvg(){ return 1;};
}

包的概念

  • 包的作用?

包就是文件夹,用来管理各种不同功能的java类

  • 包名的书写规则?

公司域名反写+包的作用,需要全部英文小写,见名知意

  • 什么是全类名?

包名+类名

  • 什么时候需要导入包,什么时候不需要?
  1. 使用同一个包中的类时,不需要导入包
  2. 使用java.lang包中的类时,不需要导包
  3. 其他情况都需要导入包
  4. 如果同时使用两个包中的同名类,需要用全类名

为了更好的管理类,把多个类收集在一起称为一组称之为软件包。

*   在文件的最上方加上一个package语句指定该代码在哪个包中

对象

blog.csdn.net/lqt214133/a…

面向对象三大特性,封装、继承和多态

封装

将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口和对象进行交互。也就是对类内部的实现细节进行了隐藏(封装)对外只提供一些公开的接口,供其他用户进行访问。

  • private:只能在当前类中访问
  • default:在同一个包中的类可以访问,是默认权限
  • protected:主要在继承中使用,可以被子类访问
  • public:任何地方的类都可以使用

继承 (inheritance )

是面向对象的另外一个基本概念,利用继承,可以基于已存在的类构造一个新类。继承已存在的类就是复用这些类的方法和属性。在此基础上还可以添加一些新的方法和属性以满足新的需求。通过继承,可以达到对重复代码复用,减少代码量。 共性的抽取,实现代码复用。

  1. 构造方法不能继承
  2. 成员变量 public 和private 都能继承(private 不能直接使用)
  3. 成员方法 public 可以继承 private 不能继承

虚方法表

继承时,把这些方法放到了虚方法表中了

    非privatestaticfinal

在子类中可以直接使用父类的成员变量,当子类中存在与父类相同的成员变量时优先访问自己的成员变量,成员变量访问遵循就近原则,自己有就优先访问自己的,如果没则在父类中找,如果父类中也没有就会编译报错。

super关键字

在编写代码时,由于设计不好,或者场景需求,子类和父类中可能会存在相同名称的成员,如果要在子类方法中访问父类同名成员时,直接访问是无法做到的,在Java中提供了super关键字,可以在子类方法中访问父类成员。

super关键字只能在非静态方法中使用,在子类中访问父类的成员变量和方法。

super与this:

相同点: 都是java中的关键子;

只能在非静态方法中使用,用于访问非静态成员方法和属性;

在构造方法中调用时必须是构造方法的第一条语句,因此不能同时存在

不同点: this是当前对象的引用,而super则是相当于子类对象中从父类继承下来的部分成员的引用。

在非静态成员方法中,this用来访问本类的方法和属性,super用来访问父类的继承下来的方法和属性。

在构造方法中,this()用于调用本类的构造方法,super()用于调用父类的构造方法,两种调用不能同时存在,因为这两种调用都必须四构造方法的第一条语句。

构造方法中一定会存在super()的调用,哪怕没有写,编译器也会自行添加,而this()则不会。

3.2.3子类的构造方法

子类对象构造时,需要先调用父类构造方法,然后执行子类构造方法

class SuperClass{
    int a = 1;
    public void methob1(){
        System.out.println("父类中的mothob1()方法");
    }
}
 
class SubClass extends SuperClass{
    int a = 2;
 //`@Override`注解是一个元数据(metadata),它告诉编译器你打算重写父类中的一个方法。
 //当你在子类中写了一个方法,并且希望这个方法覆盖(重写)父类中的同名方法时,
 //你可以在这个方法上使用`@Override`注解。
    @Override  
    public void methob1() {
        System.out.println("子类中的mothob1()方法");
    }
    {
        System.out.println(a);
        System.out.println(super.a);
        methob1();
        super.methob1();
    }
}
public class Animal {
    String name;
    int age;
    float weight;
 
    public void eat() {
        System.out.println(name + "正在吃饭");
    }
 
    public void sleep() {
        System.out.println(name + "正在睡觉");
    }
}
 
public class Cat extends Animal{
    void mew() {
        System.out.println(name + "喵喵喵");
    }
    public void catchMouse(){
        System.out.println(name + "正在抓老鼠");
    }
}
 
public class Dog extends Animal{
    void Bark() {
        System.out.println(name + "汪汪汪");
    }
    public void lookDoor(){
        System.out.println(name + "在看门");
    }
}

就近原则

先在局部位置找->本类成员位置找->父类成员位置找,逐级往上

public class GoodInfo {
    public static void main(String[] args) {
        Zi z = new Zi();
        z.show();
    } 
} 
class Ye{
    String name ="ye";
}
class Fu extends Ye {
    String name ="fu";
}
class Zi extends Fu {
    String name ="zi";
    public void show(){ 
    String name = "showName";
    System.out.println(name);  //showName
    System.out.println(this.name); //zi
    System.out.println(super.name); //fu 
    
 
    //就近原则,都能打印
    System.out.println(color); //yellow
    System.out.println(this.color); //yellow
    System.out.println(super.color); //yellow
 }

多态

什么是多态?

对象的多种形态

多态的前提

有继承/实现关系
有父类引用指向子类对象
有方法的重写

多态的好处

 使用父类型作为参数可以接收所有子类对象,体现了多态的扩展性和便利
 

创建对象(多态方式)

// Fu f = new Zi()

f.name //拿到的是Fu中的name

调用成员变量:编译看左边,运行也看左边

编译看左边:javac 编译代码的时候会看左边父类中有没有这变量,如果有编译成功,否则失败
运行也看左边:java 运行代码的时候,实际获取的就是左边父类中成员变量的值

调用成员方法:编译看左边,运行看右边

编译看左边:javac 编译代码的时候会看左边父类中有没有这个方法,如果有编译成功,否则失败
运行看右边:java 运行代码的时候,实际运行的是子类中的方法
因为子类对父类的方法进行了重写

多态的弊端,不能调用子类的特有的方法

比如下方的 Dog特有的eat方法,就调用不了,因为 编译看左边,运行看右边,编译的时候区Ani父类中去查找,父类中没有eat方法,就会直接报错了

解决方案:

//变回子类型
Dog d = (Dog) a
d.eat()

实例:

class Ani{
    String name = "动物";
    public void show() {
        System.out.println(this.name);
    }
}
class Dog extends Ani{
    String name = "狗";
    @Override
    public void show() {
        System.out.println(this.name);
    }
    public void eat(){
        System.out.println("狗在吃骨头")
    }
}
public class Animal{
    public static void main(String[] args) {
        Ani a = new Dog();
        System.out.println(a.name); //动物
        a.show(); //狗
    }
}

也就是下边所说的向上转型和向下转型

多态通俗来讲,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。 以动物为例,同样都是吃,狼吃肉,羊吃草这便是多态,总的来说就是同一件事,发生在不同对象身上就会产生不同的结果

多态的实现条件

在Java中要实现多态,就必须在继承体系下,且子类必须对父类中的方法进行重写,并且可以通过父类的引用调用重写的方法 多态体现: 在代码运行时,当传递不同类对象时,会调用对应类中的方法

重写

重写(Override)是指的是子类对父类中已有的方法重新实现。在重写过程中,子类需要按照和父类相同的方法签名(即方法名、参数列表)来定义自己的方法体,可以在方法体中重新定制适合子类的具体实现。

重写的前提是父类方法必须是非静态、非私有、非final修饰和非构造的方法。因为静态方法是与类关联而不是对象,私有方法不能被子类访问,而final修饰的方法被称为密封方法是不可重写的。

重写的好处在于子类可以根据自身的特定需求来定义特定的行为,即子类能够根据需要实现父类的方法。这样可以提供更灵活和多样化的功能。同时,通过重写,子类可以修改和优化父类的行为,实现代码的复用和扩展。

向上转型和向下转型

向上转型

向上转型,JAVA中的一种调用方式。向上转型是对父类的对象的方法的扩充,即

父类的对象可访问子类从父类中继承来的和子类重写父类的方法。

向上转型后, 不能使用原来子类中特有的字段,和方法

语法格式:父类类型 对象名 = new 子类对象

class Animal {
    String name;
    int age; 
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }; 
    public void say() {
        System.out.println("animal say" + name);
    }; 
    public void eat() {
        System.out.println("animal eat");
    } 
}; 
class Dog extends Animal {
    public Dog (String name, int age) {
        super(name, age);
    }
    public void say() {
        System.out.println("dog say" + name);
    }

    public void colorGet() {
        say();
        super.say();
    }
} 
public class ExtendsClass {
    public static void main(String[] args) {
        Animal dd = new Dog("小黑",3); //向上转型的声明
        dd.say();  //dog say小黑,访问的是 子类的say
        dd.eat();  //可以访问父类的方法
        dd.colorGet(); 
     //会报错,colorGet 是子类特有的方法,只能访问子类从父类中继承来的和子类重写父类的方法

    }
} 
//**向上转型的优点:** 让代码实现更简单灵活
//**向上转型的缺点:** 不能调用子类特有的方法

向下转型

将一个子类对象经过向上转型之后当成父类方法使用,再无法调用子类的方法,但有时候可能需要调用子类特有的方法,此时:将父类引用再还原为子类对象即可,即向下转型。

  Animal animal1 = dd;
  if(animal1 instanceof Dog){//判断是否可以安全转换
      dd = (Dog)animal1;
      dd.lookDoor();
  }
 

内部类

在一个类的里面再定义一个类

当一个事务的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构由只为外部事务提供服务,那么此时可以考虑使用内部类。内部类可以访问外部类的所有成员,包括私有成员,从而方便地为外部事务提供服务。

内部类是Java中一种特殊的类定义方式,它可以被定义在其他类或者方法的内部。内部类也是封装的一种体现,可以被用来实现一个类的私有成员或者私有方法。内部类只有在外部类中是可见的,对外是不可见的,从而实现了隐藏和封装的效果。

总的来说,内部类在Java中是一种实现封装和提供服务的机制,可以将一个事务的内部结构完整地描述出来,同时也增强了代码的可读性和可维护性。

  1. 成员内部类(Member Inner Class)
  2. 局部内部类(Local Inner Class)
  3. 匿名内部类(Anonymous Inner Class)
  4. 静态内部类(Static Inner Class)
class OutClass{
    int a = 1;
    static int b = 2;
    String e = "外部类";
    //实例内部类
    class InClass{
        int c = 3;
        static final int d = 4;//常量
        String e = "实例内部类";
 
        public void print(){
            System.out.println(a);
            System.out.println(b);
            System.out.println(c);
            System.out.println(d);
            System.out.println(e);
            System.out.println(OutClass.this.e);
        }
 
    }
 
}
 
public class Test {
    public static void main(String[] args) {
        //1、创建外部类对象
        OutClass outClass = new OutClass();
        //2、创建内部类对象
        OutClass.InClass inClass = outClass.new InClass();
        inClass.print();
    }
}

抽象类

1、抽象类的作用是什么样的?

  • 抽取共性时,有一些共性无法确定方法体,就把方法定义为抽象类
  • 强制让子类按照某种格式重写
  • 抽象方法所在的类,必须是抽象类

2、抽象类和抽象方法的格式?

public abstract 返回值类型 方法名(参数列表)
public abstract class 类名 {}

3、继承抽象类有哪些要注意的?

继承的class 要么重写抽象类中的所有的抽象方法,要么 也是一个抽象类

在Java中如果一个类被abstract修饰则被称为抽象类,抽象类中被abstract修饰的方法称为抽象方法,抽象方法不用给出具体的实现体。抽象类也是类内部可以包含普通方法和属性构造方法。

抽象类代表着没有人可以创建出该类的实例,它除了被继承以外,是没有用途,没有值,没有目的

public abstract class Shape {
    double a;
 
    abstract public void draw();
    abstract public void colour();
}

抽象类的特性

1、使用abstract修饰的类就是抽象类

2、抽象类当中可以包含普通类所能包含的成员

3、抽象类和普通类不同的是可以包含抽象方法

4、抽象方法是使用abstract修饰的这个方法没有具体实现

5、抽象类不能被实例化

接口

讲解

接口就是一种规则,是对行为的抽象

接口中成员的特点:

成员变量:    
    只能值常量
    默认修饰符: public static final
构造方法:没有
成员方法:
    jdk7以前只能 有 抽象方法,默认修饰符:public abstract
    jdk8新特性:接口中可以定义有方法体的方法
    jdk9新特性:接口中可以定义私有方法
     

构造方法

  • 构造方法的名字要与类名相同;
  • 没有返回值;
  • 创建对象时编译器自动调用,并且在对象的生命周期内只调用一次;
  • 构造方法可以重载;
class Date {
    public int year;
    public int month;
    public int day;
 
    public Date(int year, int month) {
        System.out.println("带两个参数的构造方法");
        this.year = year;
        this.month = month;
    }
 
    public Date(int year, int month, int day) {
        System.out.println("带三个参数的构造方法");
        this.year = year;
        this.month = month;
        this.day = day;
    }
    public void printDate(){
        System.out.println(this.year+"-"+this.month+"-"+this.day);
    }
}
public class Test {
    public static void main(String[] args) {
        Date d1 = new Date(2023,9,27);
        Date d2 = new Date(2023,9);
        d1.printDate();
        d2.printDate();
    }
}
// 定义一个简单的类:Person
 
public class People {
    //成员变量
    private String name;
    private int age;

    //构造器 可以重载 这里类似于设置默认值
    //构造方法中可以通过this调用其他构造方法,this()必须为构造方法的第一条语句。
    public People() {
        this("张三", 18);
    }
    //构造器
    public People(String name, int age) {
        this.name = name;
        this.age = age;

    }
    // 成员方法
    public void say() {
        System.out.println("我是" + this.name + "今年" + this.age + "岁");
    }

    public static void main(String[] args) {
        People p1 = new People("里斯",20);
        People p2 = new People();

        p1.say();  //我是里斯今年20岁
        p2.say();  //我是张三今年18岁

    }
} 

修饰符

类修饰符

public(访问控制符),将一个类声明为公共类,他可以被任何对象访问,一个程序的主类必须是公共类。

abstract,将一个类声明为抽象类,没有实现的方法,需要子类提供方法实现。

final,将一个类生命为最终(即非继承类),表示他不能被其他类继承。

friendly,默认的修饰符,只有在相同包中的对象才能使用这样的类。

成员变量修饰符

public(公共访问控制符),指定该变量为公共的,他可以被任何对象的方法访问。

private(私有访问控制符)指定该变量只允许自己的类的方法访问,其他任何类(包括子类)中的方法均不能访问。

protected(保护访问控制符)指定该变量可以别被自己的类和子类访问。在子类中可以覆盖此变量。

friendly ,在同一个包中的类可以访问,其他包中的类不能访问。

final,最终修饰符,指定此变量的值不能变。

static(静态修饰符)指定变量被所有对象共享,即所有实例都可以使用该变量。变量属于这个类。 被static修饰的成员变量,叫做静态变量。

特点:被所有实例化对象共享

调用方式:

类名.  调用(推荐) 
对象名调用

静态变量是随着类的加载而加载的,优先于对象出现 堆内存中开辟一个静态区,存储,所有对象共享

被sataic修饰的成员方法,叫静态方法

class Student{
    String name;
    String gender;
    static String classes = "1班";
 
    public Student(String name, String gender) {
        this.name = name;
        this.gender = gender;
    }
 
    public void print(){
        System.out.println("姓名:" + this.name+"性别:" + this.gender + "班级:" + this.classes);
    }
}
public class Test {
    public static void main(String[] args) {
        Student student1 = new Student("张三","男");
        Student student2 = new Student("李四","男");
        Student student3 = new Student("王五","女");
        student1.print();
        student2.print();
        student3.print();
    }
}

1:非静态成员变量:需要创建对象来访问

2:静态成员变量:使用类名直接调用,也可以通过对象访问

使用场景: 当对象中出现共享数据时

transient(过度修饰符)指定该变量是系统保留,暂无特别作用的临时性变量。

volatile(易失修饰符)指定该变量可以同时被几个线程控制和修改。

方法修饰符

public(公共控制符)

private(私有控制符)指定此方法只能有自己类等方法访问,其他的类不能访问(包括子类)

protected(保护访问控制符)指定该方法可以被它的类和子类进行访问。

final,指定该方法不能被重载。

static,指定不需要实例化就可以激活的一个方法。可以直接用   类名.方法名() 的方式调用

可以使用类名直接调用

1:静态函数中不能访问非静态成员变量,只能访问静态变量。

2:静态方法不可以定义this,super关键字.

3:因为静态优先于对象存在.静态方法中更不可以出现this super

4:非静态函数:非静态函数中可以访问静态成员变量

使用场景:当函数中没有访问到非静态数据时,一般多见于工具类中,因为方便使用 类名.方法名()来使用工具。

synchronize,同步修饰符,在多个线程中,该修饰符用于在运行前,对他所属的方法加锁,以防止其他线程的访问,运行结束后解锁。

native,本地修饰符。指定此方法的方法体是用其他语言在程序外部编写的。

final

  • 1、final修饰方法:最终方法,不能被重写
  • 2、final修饰类:最终类,不能被继承
  • 3、final修饰变量:是常量,不能被修改

基本数据类型:变量的值不能修改

引用数据类型,地址值不能修改,内部的属性值可以修改

常量命名规范:单个单词全部大写,多个单词,全部大写,单词之间用下划线连接

方法

方法(method)完成某一个特定功能的代码块。

修饰符 返回值类型 方法名(参数列表){
    //代码省略... 
    return 结果; 
}
  • 修饰符: public static 目前固定写法
  • 返回值类型: 表示方法运行的结果的数据类型,方法执行后将结果返回到调用者
  • 参数列表: 方法在运算过程中的未知数据,调用者调用方法时传递
  • return: 将方法执行后的结果带给调用者,方法执行到 return ,整体方法运行结束
  • 小贴士:return 结束; 这里的结束在开发中,我们正确的叫法成为方法的返回值

tips:

  • 定义位置:类中方法外,不能嵌套定义
  • 方法必须先定义,再使用
  • void表示无返回值,可以省略return,也可以单独的书写return
  • 不能在return后面写代码,return意味着方法结束,所有后面的代码记永远都不会执行,属于无效代码

方法重载overload

也就是方法重写

1、重写的方法名称,形参列表必须和父类中的一致

2、子类重写父类方法时,访问权限子类必须大于父类(空着不写<protected<public)

3、子类重写父类方法时,返回值类型必须小于等于父类(不容易理解)

4、建议:重写的方法尽量和父类保持一致

5、只有能被添加到虚方法表中的方法才能重写 (非private 非static 非final)

  • 在同一个类中,具有相同的方法名, 参数列表不同(参数的个数、类型、顺序不同),与返回值无关。

  • 参数列表:个数不同,数据类型不同,顺序不同。

  • 重载方法调用:JVM通过方法的参数列表,调用不同的方法。

  • 重载仅对应方法的定义,与方法的调用无关,调用方式参照标准格式。
  • 重载仅针对同一个类中方法的名称与参数进行识别,与返回值无关,换句话说不能通过返回值来判定两个方法是否相互构成重载。

引号用于表示不可变字符串,而单引号表示字符。

字符串的操作方法:blog.csdn.net/weixin_6976…

字符串的比较

  • equals()方法
  • ==
  • equalsIgnoreCase()方法
  • compareTo()方法

equals() 方法是最常用的比较字符串内容的方法。它比较两个字符串的内容是否相等,返回一个布尔值。

String str1 = "abcdef";
String str2 = "Abcdef";
boolean ret = str1.equals(str2);
System.out.println(ret);

使用==进行比较时

对于基本数据类型:比较的是数据值

对于引用数据类型:比较的是地址值

String str1 = "abcdef";
String str2 = "abcdef";
String str3 = new String("abcdef");
String str4 = new String("abcdef");
System.out.println(str1 == str2); //true
System.out.println(str1 == str3);//false
System.out.println(str3 == str4); //false
//JVM为了避免字符串的重复创建,节省内存,
//提升性能,维护了一块特殊的内存空间,即字符串池(String Pool)

//当创建一个字符串时,JVM首先会在字符串池中查找是否存在该字符串,
//若不存在,则在字符串池中创建该字符串;若字符串中已存在该字符串,则直接将池中字符串的地址返回

//当通过new的方式创建对象时,创建出来的对象都是存放在堆栈里面的,每new一次则是在堆栈中创建一个新的对象。

equalsIgnoreCase() 方法的作用与语法与equals()方法相同,唯一的不同点在于equalsIgnoreCase()方法在比较时不区分大小写

compareTo()方法
compareToIgnoreCase(String str) 方法:与compareTo方式相同,但是忽略大小写比较

//比较两个字符串,逐一比较每个字符,当相比较的两个字符不同时,返回不同字符的ASCII码的差值
String str1 = "abcdef";
String str2 = "abcDef";
int ret = str1.compareTo(str2);
System.out.println(ret);  //32

//若两个字符串长度不同,但参与比较的字符相同,则返回两个字符串长度的差值
 String str1 = "abcdef";
 String str2 = "abc";
 int ret = str1.compareTo(str2);
 System.out.println(ret);  //3
 //**返回正数表示str1 > str2 ,返回负数表示str1 < str2,返回0表示str1 与str2相等**

Scanner

Scanner类是Java标准库中的一个类,位于java.util包中。它用于解析基本类型(如intdouble等)和字符串,可以从多种输入源读取数据,包括控制台、文件、字符串等。

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {

        // 创建Scanner对象,从控制台读取输入
        //`System.in` 是 `System` 类的一个静态成员变量,它是一个 `InputStream` 类型的对象。
        //它代表了标准输入流,默认情况下与键盘输入相关联。
        //因此,当你看到 `Scanner scanner = new Scanner(System.in)` 这行代码时,
        //它实际上是在创建一个 `Scanner` 对象,该对象可以用来读取从键盘输入的数据。
        Scanner scanner = new Scanner(System.in);

        System.out.print("Enter your name: ");
        String name = scanner.nextLine(); // 读取一行字符串

        System.out.print("Enter your age: ");
        int age = scanner.nextInt(); // 读取一个整数

        System.out.println("Hello, " + name + "! You are " + age + " years old.");

        scanner.close(); // 关闭Scanner对象
    }
} 
  • nextLine() :读取一行字符串,包括空格。

  • next() :读取下一个单词(以空格或换行符分隔)。

  • nextInt() :读取一个整数。

  • nextDouble() :读取一个双精度浮点数。

  • nextBoolean() :读取一个布尔值。

  • nextByte() :读取一个字节。

  • nextShort() :读取一个短整数。

  • nextLong() :读取一个长整数。

  • nextFloat() :读取一个单精度浮点数。

当嵌套循环嵌套或者 循环嵌套判断语句时,退出 外层循环

public class StudentSystem {
    public static void main(String[] args) {
        loop:  while (true) {
            System.out.println("------------------欢迎来到学生管理系统---------------------");
            System.out.println("1、添加学生");
            System.out.println("2、删除学生"); 
            Scanner sc = new Scanner(System.in);
            String chooseVal = sc.next();
           switch (chooseVal) {
                case "1":
                    System.out.println("添加学生");
                    break;
                case "2":
                    System.out.println("删除学生");
                    break;
                case "3":
                    System.out.println("修改学生");
                    break;
                case "4":
                    System.out.println("查询学生");
                    break;
                case "5":
                    System.out.println("退出");
                    //break loop;  //给循环起名字,终止它
                    //System.exit(0); //退出虚拟机运行() 
                default:
                    System.out.println("没有这个选项");
                    break;
            }
        }
    }
} 

静态方法

public class Animal { 
    //-   **定义**:实例方法是属于类的实例(对象)的方法。它们必须通过类的实例来调用。
    //-   **访问方式**:要调用实例方法,你需要先创建类的实例(对象),然后通过这个实例来调用方法。
    //-   **上下文**:实例方法可以访问类的所有成员,包括实例变量和其他实例方法。
    public void eat() {}
    
    //定义:静态方法是属于类本身的方法,而不是类的实例。它们可以通过类名直接调用,无需创建类的实例。
    //访问方式:静态方法可以直接通过类名来调用,也可以通过类的实例调用,
    //但通常推荐使用类名调用以提高代码的可读性。
    //**上下文:静态方法只能访问类的静态成员(静态变量和其他静态方法),不能直接访问实例成员。
    public static void eat1(){}
} 

常用API

ArrayList

ArrayList<String> list = new ArrayList<>();
//添加
Boolean flg = list.add("A");
list.add("B");
//删除
Boolean aa = list.remove("A");
String li = list.remove(0);
//修改
list.set(0, "C");
//查询
String s = list.get(0);
//遍历
for (int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i));

}
for (String str : list) {
    System.out.println(str);
} 

Math

System

Runtime

集合

Java 集合,也叫作容器,主要是由两大接口派生而来:一个是 Collection接口,主要用于存放单一元素;另一个是 Map 接口,主要用于存放 键值对

  • List:存储的元素是有序可重复的。
  • Set:存储的元素是无序不可重复的。
  • Queue: 按特定的排队规则来确定先后顺序,可重复
  • Map: 使用键值对(key-value)存储,key 是无序的、不可重复的,value 是无序的、可重复的,每个键最多映射到一个值。

声明数组

 //声明一个整型数组
int[] intArray; 
4// 声明一个字符串数组
5String[] stringArray; 
7// 初始化数组
8int[] intArray = new int[10]; // 创建一个长度为10的整型数组
9String[] stringArray = new String[]{"a", "b", "c"}; // 创建并初始化一个字符串数组 

声明集合

// 初始化List集合 
List<String> userIds = new ArrayList<>();
int[] arr = {1,2,3,4}

List<String> stringList = new ArrayList<>(); // 创建一个ArrayList实例

// 添加元素到集合
stringList.add("a");
stringList.add("b");
stringList.add("c");

// 声明并初始化
List<String> stringList = new ArrayList<>(Arrays.asList("a", "b", "c")); 


// 声明并初始化一个Set集合
Set<String> stringSet = new HashSet<>();


// 创建一个 LinkedHashSet 
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>(); 
// 添加元素 
linkedHashSet.add("A"); 
linkedHashSet.add("B"); 
linkedHashSet.add("C");
-   **有序性**:LinkedHashSet 会保持元素的插入顺序,即元素被添加到集合中的顺序就是它们在集合中的顺序。
-   **唯一性**:与 HashSet 一样,LinkedHashSet 保证元素的唯一性,不允许重复元素。
-   **性能**:由于 LinkedHashSet 使用哈希表存储元素,因此它提供了快速的查找性能。同时,它还使用链表来维护元素的插入顺序。


// 声明并初始化一个Map集合
Map<String, Integer> map = new HashMap<>();

// 创建一个 TreeMap
TreeMap<String, Integer> treeMap = new TreeMap<>();

// 插入键值对
treeMap.put("apple", 10);
treeMap.put("banana", 20);
treeMap.put("orange", 30);


// 声明并初始化LinkedList
LinkedList<String> linkedList = new LinkedList<>();
 

Stream

链接

public class Demo {
    public static void main(String[] args) {
        ArrayList<String> names = new ArrayList<>();
        Collections.addAll(names, "张三丰", "张无忌", "周芷若", "赵敏", "张三", "韦一笑");

        // 方案一:传统遍历
        List<String> list = new ArrayList<>();
        for (String name : names) {
            if (name.startsWith("张") && name.length() == 3) {
                list.add(name);
            }
        }
        System.out.println(list); // [张三丰, 张无忌]


        // 方案二:Stream
        List<String> list2 = names.stream()
                .filter(name -> name.startsWith("张") && name.length() == 3)
                .collect(Collectors.toList());
        System.out.println(list2); // [张三丰, 张无忌]
    }
} 

Stream的方法

filter:根据给定的条件过滤出符合条件的元素。 map:将每个元素通过给定的函数映射成另一个元素(对每一项数据进行加工处理)。 peek:对流中的每个元素执行操作并返回一个新的流,主要用于调试。 sorted:对Stream中的元素进行排序。

public static void sorted() {
    List<Integer> numbers = Arrays.asList(8, 3, 6, 7, 5);
    
    List<Integer> sortedNumbers = numbers.stream()
            .sorted((a, b) -> a - b)
    .collect(Collectors.toList());

    System.out.println(sortedNumbers); // [3, 5, 6, 7, 8]
}

distinct:去除Stream中的重复元素。

public static void distinct() {
    List<String> daxias = Arrays.asList("张无忌", "赵敏", "张无忌", "周芷若", "赵敏");

    List<String> distinctDaxias = daxias.stream()
            .distinct()
    .collect(Collectors.toList()); // [张无忌, 赵敏, 周芷若]

    System.out.println(distinctDaxias);
}

reduce:对Stream中的元素进行归约操作,可以实现求和、求最大值、求最小值等操作。

public static void reduce() {
    List<Integer> numbers = Arrays.asList(8, 3, 6, 7, 5);

    // 求和
    Integer sum1 = numbers.stream().reduce((a, b) -> a + b).get();
    Integer sum2 = numbers.stream().reduce(Integer::sum).get();

    System.out.println("sum1: " + sum1 + ",sum2:" + sum2); // sum1: 29,sum2:29

    // 最大值
    Integer max1 = numbers.stream().reduce((a, b) -> a > b ? a : b).get();
    Integer max2 = numbers.stream().reduce(Integer::max).get();
    System.out.println("max1:" + max1 + ",max2:" + max2); // max1:8,max2:8

	// 最小值
    Integer min1 = numbers.stream().reduce((a, b) -> a < b ? a : b).get();
    Integer min2 = numbers.stream().reduce(Integer::min).get();
    System.out.println("min1:" + min1 + ",min2:" + min2); // min1:3,min2:3
}

limit:限制Stream中元素的数量。

public static void limit() {
    List<Integer> numbers = Arrays.asList(8, 3, 6, 7, 5);
    List<Integer> limitedNumbers = numbers.stream()
		.limit(3)
		.collect(Collectors.toList());
    System.out.println(limitedNumbers); // [8, 3, 6]
}

skip:跳过Stream中的前几个元素。

public static void skip() {
    List<Integer> numbers = Arrays.asList(8, 3, 6, 7, 5);
    List<Integer> limitedNumbers = numbers.stream()
		    .skip(2)
		    .collect(Collectors.toList());

    System.out.println(limitedNumbers); // [6, 7, 5]
}

lambda表达式

//也就类似于js中的箭头函数
stream.filter(s -> s.startsWith("张")).forEach(n -> System.out.println(n));
 

方法引用

静态: 类名::方法名 构造方法: 类名::方法名

引用成员方法: 其他类: 其他类对象::方法名 本类:this::方法名 父类:super::方法名

ArrayList<String> names2 = new ArrayList<>();
Collections.addAll(names2,"1","2","3","4","5","6"); 
names2.stream().map(Integer::parseInt).forEach(System.out::println);

File

1、file对象表示路径,可以是文件,可以是文件夹 这个路径可以是存在的,可以是不存在的

2、绝对路径和相对路径 绝对路径是带盘符的,相对路径是不带盘符的,默认到当前项目下去找

3、File三种构造

public File (String pathName)
public File(String parent , String  child)
public File(File parent ,String  child)
String str = "c:\users\Desktop\a.text";
File file = new File(str);
System.out.println(file);v

IO 流

  • 流的方向: 输入流,输出流

  • 操作文件类型:

    字节流:所有类型文件
    字符流:纯文本文件 .txt .md .xml .lrc

写出数据

FileOutputStream fos = new FileOutputStream("C:\Users\zhangjinzhong\Desktop\aa\aa.txt");
fos.write(97);
fos.close();