java语法


补充

1. 字符串比较
== 比较两个对象的地址是否相等
equals 比较两个对象的内容是否相等例如:

String a="fsd",b="fsafsdd";

boolen od=a.equals(b);//判断a串和b串是否相等

一、基本格式

修饰符 class 类名{
		代码
		//类名通常用首字母大写形式
		//类名和文件名必须一致
}

变量名:由数字、字母、下划线、美元符号($)组成,不能以数字开头


二、数据类型

1、基本数据类型

整数型:short 、 int 、long、byte
浮点数:float 、double
字符型:char
布尔型:boolean

2、引用数据类型

类:class
接口:interface
数组
枚举:enum
注解:annotation


三、方法

1、方法

方法是一段可重复调用的代码。(类似于c++中的子函数)

修饰符 返回值类型 方法名(参数类型 参数名1,参数类型 参数名2....){
	
	return 返回值;//void没有返回值
}

2、方法的重载

在同一个作用域中,方法名相同但参数个数或者参数类型不同的方法

public class Main {
    public static void main(String[] args) {
        
        int n=add(1,2);
        int m=add(1,2,3);
        double p=add(1.2,1.3);
        
        System.out.println("Hello world!");
    }
    //同一个方法名,不同的参数类型或个数,是允许的
    public static int add(int x,int y){
        return x+y;
    }
    
    public static int add(int x,int y,int z){
        return x+y+z;
    }
    public  static double add(double x,double y){
        return x+y;
    }
}

3、构造方法

作用: 在实例化对象的时候为变量赋值

注意:

  • 构造方法名字要和类名一致
  • 构造方法前不能有任何返回值类型的声明
  • 不能在构造方法中return一个值,但是,可以单独写return作为方法的结束

class role {
    String name;
    public role(String name){
        this.name=name;
    }
}
public class Main{
    public static void main(String[] args) {
        role stu=new role("宁");//调用构造方法进行初始赋值
    }
}

在定义了有参构造方法之后,无参的构造方法不能在访问,即代码


class role {
    String name;
    public role(String name){
        this.name=name;
    }
}
public class Main{
    public static void main(String[] args) {
        role stu=new role();//调用 无参 构造方法进行初始赋值
    }
}

错误的,如果要用无参的构造方法需要重载一个无参的构造方法,同理,构造方法可以进行多次重载,但是要遵循构造方法的写法规范

4.静态方法

访问同静态变量一样,也可以通过实例化的对象访问

注意:

  • 静态方法只能访问静态成员
  • 非静态成员需要先创建对象才能访问

5.继承中方法的重写

有时需要在子类中对继承的方法进行一些修改,即对父类的方法进行重写

在子类中,重写的方法需要和父类中被重写的方法具有相同的方法名、参数列表、返回值类型!!!!!!

在重写的时候,注意:

  • 子类重写父类的方法的时候,不能使用比父类更严格的访问权限,例如:父类是用public修饰,子类就不能用protected以及更低的访问权限修饰

四、数组

数据类型[] 数组名;
数组名=new 数据类型[长度];//和C同样的从下标0开始
public class Main {
    public static void main(String[] args) {
        //初始化1
       int[] x;
       x=new int[100];
       
       //初始化2
       int[] y=new int[]{元素,元素....};
       
       //初始化3
       int[] z={元素,元素..};
       
	   int u=x.length;//获取数组长度
	   
    }
}

二维数组 :和一维基本相同

数据类型[][] 数组名=new 数据类型[行数][列数]

//列数不确定
数据类型[][] 数组名=new 数据类型[行数][]

//和一维的初始化2,3一样

五、类和对象

1、类

类是对象的抽象,用于描述一组对象的共同特征和行为。
类中可以定义成员变量和成员方法。
成员变量用于描述对象的特征,也被称为对象的属性
成员方法用于描述对象的行为简称对象。

class 类名{
    成员变量;
    成员方法;
}

class  student{
    //成员变量
    string name;
    int age=30;//成员变量
    string sex;
    //成员方法
    void read(){
    	int age=50;//局部变量
        System.out.println("成员方法");
    }
    
}

允许局部变量和成员变量同名,但此时,方法中的变量值为局部变量的值,上面age就是50

2、对象(类比结构体)

类名 对象名=null;
对象名=new 类名();

//或者
类名 对象名=new 类名();

//创建好实例对象之后,可以使用了

对象名.属性名
对象名.方法名

举例:


class  student{
    string name;
    int age;
    string sex;
    
    void read(){
        System.out.println();
    }
}
public class Main {
    public static void main(String[] args) {
        student st=new student();
    }
}

六、访问控制权限

private私有访问权限,只能在本类中访问
default默认访问权限,如果一个类中的属性或方法没有任何访问权限的生命,则为默认访问权限,只能被本包中的类访问
protected 受保护的访问权限,只能被本本包及不同包的子类访问
public公共访问权限,可以被所有的类访问,不论是否在同一个包中

注意
       局部变量没有访问控制权限,因为局部成员只在其所在的作用 域内起作用

七、封装性

类的封装:是指将对象的状态信息 隐藏在对象内部不允许外部程序直接访问对象的内部信息,而是通过该类提供的方法实现对内部信息的访问

具体方法:在定义一个类的时候将类中的属性私有化,即使用private修饰,私有属性只能被本类访问
如果需要外界访问或修改,要提供公共的方法


class role{
    private string name;//私有成员

    public string getName() {//公有方法
        return name;
    }

    public void setName(string name) {//公有方法
        this.name = name;
    }
}
public class Main{
    public static void main(String[] args) {
        role stu=new role();
    }
}

八、关键字

1. this

如代码:


class role {
    String name;
    public role(String name){
        this.name=name;
    }
}
public class Main{
    public static void main(String[] args) {
        role stu=new role("宁");//调用构造方法进行初始赋值
    }
}

由于name变量不仅作为成员变量,也作为的构造方法的形参,在使用时会产生错误,所以,将本类的成员变量namethis.name进行调用。

this不仅可以调用本类的成员变量,也可以在本类中调用本类的成员方法、构造方法(不是必须,条件可以的话,也可不用写this

在调用构造方法的时候应注意:

  • 只能在构造方法中调用其他的构造方法,不能在成员方法中调用构造方法
  • 在构造方法中,使用this调用其他构造方法是,必须位于第一行,且只能出现一次

class role {
    String name;
    public role(){ }
    public role(String name){
        this.name=name;
        this.role();//错误,不在第一行
    }
}
public class Main{
    public static void main(String[] args) {
        role stu=new role("宁");//调用构造方法进行初始赋值
    }
}

  • 不能在一个类的两个构造方法中使用this互相调用

2、static

用于修饰类的成员,如成员方法、成员变量、代码块等

如果在Java程序中用static修饰属性,则该属性成为静态属性(也称全局属性),可以用类名直接访问

类名.属性名

class role {
  static  String name="ppp";
    int age;

}
public class Main{
    public static void main(String[] args) {
        System.out.println(role.name); //通过类名直接访问
        
        role r1=new role(),r2=new role();
        r1.age=10;
        r2.age=20;
        role.name="iii";
    }
}

/*
	如果 name 没有 static 修饰,那么不能通过类名直接访问
	当 name 用 static 用修饰的时候,如果修改 name 的值, r1 和 r2 的
name 都会修改,如果没有 static 修饰,则不会同时修改

图释:
在这里插入图片描述

注意:

  • 该关键字不能修饰局部变量

3.super

当子类重写了父类的方法后,子类对象将无法访问父类中被重写的方法,为了解决该问题,super便产生了

(1)使用super访问父类的非私有属性或方法

super.属性
super.方法(参数1,参数2.....)

(2)使用super调用父类中指定的构造方法

super(参数1,参数2.。。。);

例如:


class A {
    private String name;
    
    public A(String name){
        this.name=name;
    }
}

class B extends A{
    
    int age;
    public B(String name,int age){
        super(name);//调用父类的构造方法
        this.age=age;
    }
}
public class Main{
    public static void main(String[] args) {
 
    }
}

注意:

  • 使用super调用父类构造方法的代码必须位于子类构造方法的第一行

4. this 和 super 区别

在这里插入图片描述
由于这两个需要放到构造方法的首行,所以,他们不能同时出现

5. final

在默认情况下,所有的成员变量和成员方法都可以被子类重写,但是由的父类成员不希望被子类重写,那么该关键字产生了

使用final修饰的类不可以被继承,也就是这样的类不能派生子类

例如:

final class A {
    
}

class B extends A{
    //错误,A 类是不可继承的类
}
public class Main{
    public static void main(String[] args) {

    }
}

class A {
    public final void shout(){
        System.out.println("balabala");
    }
}

class B extends A{
    public void shout(){
        //错误,final 修饰的方法不能被子类重写
    }
}
public class Main{
    public static void main(String[] args) {

    }
}

final 修饰的变量不能修改,类似于C语言中的const,并且用其修饰的时候,变量名字要全部大写例如声明全局变量:

public static final int AGE=89;

6、 instanceof (判断是否为接口)

判断一个对象是否是某个类(或接口)的实例

格式:

对象 instanof 类(或接口)

上述 “ 对像 ” 如果是指定类的实例对像,则返回true 否则返回false

package PACAK1;

import javafx.scene.AmbientLight;

class  Animal{
    public void shout(){
        System.out.println("喵喵...");
    }
}

class Dog extends Animal{
    //重写shout方法,不是抽象类的方法,也可以不重写,看自己需求
    public void shout(){
        System.out.println("汪汪汪...");
    }
    public void eat(){
        System.out.println("不吃饭....");
    }
}

public class t1 {
    public static void main(String[] args) {
        Animal a1=new Dog();//通过向上转型实例化 Animal 对象
        System.out.println("Animal a1=new Dog():"+(a1 instanceof Animal));
        System.out.println("Animal a1=new Dog():"+(a1 instanceof Dog));
        Animal a2 = new Animal();
        System.out.println("Animal a1=new Animal():"+(a2 instanceof Animal));
        System.out.println("Animal a1=new Animal():"+(a2 instanceof Dog));
    }
}
/*
输出:
Animal a1=new Dog():true
Animal a1=new Dog():true
Animal a1=new Animal():true
Animal a1=new Animal():false
*/



九、代码块

执行循序: 静态代码块 -> 构造代码块 -> 构造方法
普通代码块是在主类中第一的代码块,所以执行循序不包括该

1.普通代码块

意思:就是直接在方法会语句中定义的代码块

错误事例:

public class Main{
    public static void main(String[] args) {
        {
            int age=10;
            System.out.println(age);
        }
        
        System.out.println(age);//错误的
    }
}

正确事例:

public class Main{
    public static void main(String[] args) {
        {
            int age=10;
            System.out.println(age);
        }
        int age=10;
        System.out.println(age);
    }
}

由单纯的{}括起来的代码为普通代码块,可以对变量起到了作用域的限定作用

2.构造块

意思:在类中定义的代码块


class role {
    String name;
    
    {
        System.out.println("构造代码块");
    }
}
public class Main{
    public static void main(String[] args) {
        role stu=new role();//调用构造方法进行初始赋值
    }
}

注意:

  • 构造代码块与构造方法、成员属性、成员方法同级
  • 在实例化对象的时候,构造块先于构造方法执行,这个构造代码块写到前面还是后面没有关系
  • 每当实例化一个对象的时候,都会先执行构造代码块,然后才会执行构造方法

3.静态代码块

使用 static 修饰的代码块


class role {
    
    static {
        System.out.println("静态代码块在此");
    }

}
public class Main{
    public static void main(String[] args) {

    }
}

注意:

  • 静态代码块只在第一次实例化对象的时候执行

十、继承

继承是指在一个现有的基础类上构建一个新的类,构建的新类被称为子类,现有的类称作父类,用关键字extends声明

class 父类名{
	
}

class 子类名 extends 父类名{

}

注意:

  • 子类虽然可以通过继承访问父类的方法和成员,但是只能访问publicprotected修饰的成员和方法,对于private , default修饰的成员和方法不能访问
  • 只允许单继承,不允许多继承,如:
class A{ }
class B{ }
class c extends A,B{ }
//这种是不允许的,不可以同时继承
  • 多个类可以继承一个父类,例如
class A{ }

class B extends A{ }
class C extends A{ }
  • 多层继承也是可以的,即一个类的父类可以在继承另外的父类,如:
class A{ }

class B extends A{ }
class C extends B{ }

// c 继承了 b 类,c 是 b 的子类,b 继承了 a 类,b 是 a 的子类,同时
// c 也是 a 的子类
  • 子类,父类的称呼是相对的,正如上面的:b 是 c 的父类,同时又是 a 的子类

十一、抽象类

定义一个类时,常常需要定义一些成员方法用于描述类的行为特征,但有写方法的实现是无法确定的,例如:定义一个 Animal 的父类,其中有shout() 方法(用于输出叫声),那么不同的子类(也就是不同的动物)对于shout() 方法的输出也就不同,那么父类中的shout() 方法就无法确定写法,于是abstract关键字就诞生了

(1)抽象方法实现不需要写出方法体,例如:

abstract 返回值类型 方法名(参数1,参数2...); //注意分号别忘了写

(2)抽象类也必须用abstract关键字修饰,语法格式:

abstract class 类名{
	属性;
	访问权限 返回值类型 方法名(参数....){
		//普通方法
	}
	
	访问权限 abstract 返回值类型 抽象方法名(参数);
}

抽象类定义规则:

  • 包含抽象方法的类必须是抽象类
  • 声明抽象类和抽象方法必须用abstract修饰
  • 抽象方法只需要声明不需要实现
  • 如果一个非抽象类继承了抽象类,那么,该类必须重写抽象类中的全部抽象方法

注意:

  • 使用abstract修饰的抽象方法不能使用private修饰

十二、接口

是一种用来定义程序的协议,它用于描述类或结构的一组相关行为

来源:接口是由抽象类衍生的一个概念,并由此产生了一种编程逻辑,可以称这种编程方式为面向接口编程

面向接口编程:将程序的不同的业务逻辑分离,以接口的形式对接不同的业务模块。接口中不实现任何业务逻辑,业务逻辑由接口的实现类完成。当业务需求变更时,只需要修改实现类中的业务逻辑,而不需要修改接口中的内容,以减少需求变更对系统产生的影响

面向接口编程,思想类比:
 鼠标,键盘等通过 USB 接口来连接计算机,如需更换只要拔掉当前的 USB 插口,换上新的即可

目的:克服单继承的限制,因为一个类只能有一个父类,而一个类可以实现多个接口,使用关键字interface声明

语法格式:

[public] interface 接口名 [extends 接口1,接口2...]{
        [public] [static] [final] 数据类型 常量名=常量;
        [public] [abstract] 返回值的数据类型 方法名(参数列表);
        [public] static 返回值的数据类型 方法名(参数列表){ }
        [public] default 返回值的数据类型 方法名(参数列表){ }
}
  • 语法 “ extends 接口1,接口2… ” 表示一个接口可以有多个父接口,父接口之间用逗号隔开
  • 接口中变量默认使用public static final进行修饰,即全局变量,抽象方法默认用public abstract修饰
  • 接口中无论使写不写访问权限,接口中方法的默认权限永远都是用public修饰

接口本身不能实例化,只能通过接口实现类的事例对象进行访问(抽象方法和默认方法),implements 关键字实现。实现类必须重写接口中所有的抽象方法

定义接口实现类语法:

修饰符 class 类名 implements 接口1,接口2.。。。{

}

综合应用:

//定义接口 Animal
interface Animal{
    int ID=1;//定义全局常量
   void shout();//定义抽象方法
}

interface Action{
    public void eat();//定义抽象方法
}

//定义 Dog 类实现 Animal 接口和 Action 接口
class Dog implements Animal,Action{

    public void eat(){
        System.out.println("喜欢吃饭");
    }
    public void shout(){
        System.out.println("汪汪汪");
    }
}
public class Main{
    public static void main(String[] args) {
        Dog dog=new Dog();//创建 Dog 类的实例对象
        dog.eat();//调用 Dog 类中重写的 eat() 方法
        dog.shout();//调用 Dog 类中重写的 shout() 方法
    }
}

补注:

  • 如果一个子类既要实现接口,又要继承抽象类,则可以写为:
修饰符 class 类名 extends 父类名 implements 接口1,接口2.。。{

}

//例如:c 类继承了 A 抽象类,并实现了 B 接口
interface B{

}

abstract A{

}
class C extends A implements B{
}
  • 接口不允许继承抽象类,但是允许接口继承接口
interface B{

}

interface A{

}
interface C extends A,B{ //定义 c 接口,同时继承了 A B 接口
}

class D implements C{
//定义 D 类实现 C 的接口
}

十三、多态

大意:不同类的对象在调用同一个方法时表现出来的多种不同行为
例如:定义了一个抽象类 animal,在该类中定义了一个抽象方法shout,那么,同过定义不同的类去继承animal类,并且重写其中的shout方法,这样就是实现了多态

十四、对象类型的转换

向上转型:子类对象 ----> 父类对象
向下转型:父类对象 ----> 子类对象

(1)、向上转型

对象可以调用子类重写父类的方法,这样当需要添加新功能时,只需要新增一个子类,在子类中对父类的功能进行拓展,而不用更改父类的代码

更改格式:

父类类型  父类对象 = 子类实例 ;
class  Animal{
    public void shout(){
        System.out.println("喵喵...");
    }
}

class Dog extends Animal{
    //重写shout方法,不是抽象类的方法,也可以不重写,看自己需求
    public void shout(){
        System.out.println("汪汪汪...");
    }
    public void eat(){
        System.out.println("不吃饭....");
    }
}

public class t1 {
    public static void main(String[] args) {
        Dog dog=new Dog(); // 创建 Dog 对象,即子类
        Animal an=dog;// 完成了向上转型
        an.shout(); // 输出 喵喵... 
    }
}

注意:

  • 转型后的父类an无法调用Dog中的eat()方法,因为eat()方法只在子类定义了

(2)、向下转型

向下转型一般是为了重新获得因向上转型而丢失的子类特性

格式:

父类类型 父类对象 = 子类实例;
子类类型 子类对象 = (子类)父类对象;
class  Animal{
    public void shout(){
        System.out.println("喵喵...");
    }
}

class Dog extends Animal{
    //重写shout方法,不是抽象类的方法,也可以不重写,看自己需求
    public void shout(){
        System.out.println("汪汪汪...");
    }
    public void eat(){
        System.out.println("不吃饭....");
    }
}

public class t1 {
    public static void main(String[] args) {
        Animal an = new Dog(); //完成了向上转型: 子类 ---> 父类
        Dog dog = (Dog) an; // 向下转型
        dog.shout();
        dog.eat();
    }
}

注意:

  • 向下转型的时候,必须先进性向上转型

十五、内部类

在一个类的内部定义的类,叫做内部类
根据内部类的位置、修饰符和定义方式不同,内部类可分为:成员内部类、局部内部类、静态内部类、匿名内部类

(1)、成员内部类

内部类可以访问外部类的所有成员、无论是何种访问权限(额。。。就是类中套类)

如果想要通过外部类访问内部类,则需要通过外部类创建内部类对象,格式:

外部类名 外部类对象 = new 外部类名() ;
外部类名.内部类名 内部类对象 = 外部类对象.new 内部类名() ;

(2)、局部内部类

:也称方法内部类。在某个局部范围定义的类,他和局部变量都是在方法中定义的,有效范围只限于方法内部

可以访问外部类的所有成员变量和成员方法
如果要在外部类中访问局部内部类的成员,只能在局部内部类的所属方法中创建局部内部类的对象,通过对象访问局部内部类的额变量和方法

class Outer{
    int m=0;
    void tes1(){
        System.out.println("外部成员方法。。。");
    }
    void test2(){
        //定义一个局部内部类,在局部内部类中访问外部变量和方法
        class Inner{
            int n=1;
            void shout(){
                System.out.println("外部成员变量m:"+m);
                tes1();
            }
        }

        //访问局部内部类中的成员和方法
        Inner inner=new Inner();
        System.out.println("局部内部类变量n= "+inner.n);
        inner.shout();
    }
}

public class t1 {
    public static void main(String[] args) {
        Outer outer=new Outer();
        outer.test2();
    }
}

(3)、静态内部类

就是用static关键字修饰的成员内部类,

与成员内部类相比:多了一个static关键字; 静态内部类只能访问外部类的静态成员

格式:

外部类名.静态内部类 变量名 = new 外部类名.静态内部类名() ;
class Outer{
    static int m=0;
    static class Inner{
        int n=1;
        //静态内部类的方法中访问外部静态变量
        void show(){
            System.out.println("访问外部静态变量 m= "+m);
        }
    }
}

public class t1 {
    public static void main(String[] args) {
        Outer.Inner inner=new Outer.Inner();

        inner.show();
    }
}

(4)、匿名内部类

匿名内部类,就是没有名字的一种嵌套类。它是Java对类的定义方式之一。
:如果 Java 调用某个方法时、如果该方法的参数是接口类型,那么在传参时,除了可以传入一个接口实现类,还可以传入实现接口的匿名内部类作为参数

为什么要使用匿名内部类?
在实际开发中,我们常常遇到这样的情况:一个接口/类的方法的某个实现方式在程序中只会执行一次,但为了使用它,我们需要创建它的实现类/子类去实现/重写。此时可以使用匿名内部类的方式,可以无需创建新的类,减少代码冗余

new 继承的父类或实现的接口名{
	匿名内部类的类体
}
interface animal{//定义一个接口
    void show();
}

public class t1 {
    public static void main(String[] args) {
        animalopa(new animal() { // 调用animalopa() 方法,参数为匿名内部类
            @Override
            public void show() {
                System.out.println("miao...");
            }
        });
    }
    public static void animalopa(animal an){//该方法为接口类型
        an.show();
    }
}

拓展:

//具体类
 class Class01 {
    public void show(String s){
        System.out.println("啦啦啦");
    }
}
//抽象类
 abstract class AbstractClass01 {
    abstract void show(String s);
}
//接口
 interface Interface01 {
    void show(String s);
}


public class t1 {
    public static void main(String[] args) {
        //重写具体类的方法
        new Class01(){
            @Override
            public void show(String s) {
                System.out.println("我是一个" + s);
            }
        }.show("具体类");

        //重写抽象类的抽象方法
        new AbstractClass01(){
            @Override
            void show(String s) {
                System.out.println("我是一个" + s);
            }
        }.show("抽象类");

        //实现接口的抽象方法
        new Interface01(){
            @Override
            public void show(String s) {
                System.out.println("我是一个" + s);
            }
        }.show("接口");
    }

}

输出:

我是一个具体类
我是一个抽象类
我是一个接口

对于@Override:


@Override注解是伪代码,用于表示被标注的方法是一个重写方法。

@Override注解,只能用于标记方法,并且它只在编译期生效,不会保留在class文件中。

@Override 检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。

@Override注解标记的方法声明,如果没有覆写或者实现超类(被继承的类)的方法声明,或者不是覆写Objectpublic方法,那么编译就会报错。
使用@Override注解,有助于我们尽早发现这样的错误:本来想声明一个“覆写”方法,却偶然声明成“重载”方法。


使用@Override注解主要有两个好处:

1)帮助自己检查是否正确的重写父类方法

2)明显的提示看代码的人,这是重写的方法

拓展:

Lambda表达式:只有一个带实现的抽象方法时,匿名内部类可以用Lambda表达式表示,可以存在其他方法,其他方法必须用default修饰

//接口
 interface Animal {
    void show();
}

public class t1 {
    public static void main(String[] args) {
        Animal stu=()->{
            System.out.println("lambda方法");
        } ;//相当于实例化的时候重写方法
        stu.show();
    }
}

如果说show()有参数:

//接口
 interface Animal {
    String show(int u);
}

public class t1 {
    public static void main(String[] args) {
        Animal stu=(u)->{//参数类型可以不写
            return u+"fsd";
        } ;//相当于实例化的时候重写方法
        String a=stu.show(1);
    }
}

如果说show()只有一个参数:
也可写为

//接口
 interface Animal {
    String show(int u);
}

public class t1 {
    public static void main(String[] args) {
        Animal stu=u->{ //小括号可以不写
            return u+"fsd";
        } ;//相当于实例化的时候重写方法
        String a=stu.show(1);
    }
}

如果说,方法体中只有一个返回语句还可以在简化:

 Animal stu=u->{ //小括号可以不写
            return u+"fsd";
        } ;//相当于实例化的时候重写方法
// 简化为
 Animal stu=u-> u+"fsd";

还可以用下面的方式重写方法:
第一种:

//接口
 interface Animal {
    String show(int u);
}

public class t1 {
    public static void main(String[] args) {
        t1 a=new t1(); //因为成员方法只能具体成员调用
        Animal animal=a::shoow;//对接口中的 show() 方法重写,用 shoow() 方法覆盖,名字可以相同,亦可以不相同
        // 双冒号必须有,建议自己重写的方法用冒号覆盖,函数库的还可以用下面的方法
        System.out.println( animal.show(2));
    }
    public String shoow(int p){
        return "fsad";
    }
}

第二种:(函数库自带的可以用)

//接口
 interface Animal {
//    String show(int u);
    int sum(int a,int b);
}

public class t1 {
    public static void main(String[] args) {
        Animal animal=(a,b)->Integer.sum(a,b);//或者 = Integer::sum ;
        System.out.println( animal.sum(8,2));
    }
}

.

.

.

一、异常

:在程序运行时可能出现的错误或非正常情况

在这里插入图片描述
1.系统错误(Error)
2.编译时异常(Exception)

  • 1.运行时异常(RuntimeException)

(1)抛出异常

当调用某个方法的时候 ,如果跟传入错误的参数,那么程序将无法继续运行,这个时候我们可以手动抛出一个异常来终止程序运行下去,同时告知上一级方法执行出现了问题

throwthrows区别:

public class t1 {
    public static void main(String[] args) {
        System.out.println(test(1,0));
    }
    public static int test(int a,int b){
        if(b==0)
            throw new RuntimeException("除数为零");//通过 throw 抛出异常
        return a/b;
    }
}

运行结果:
在这里插入图片描述
如果说抛出了一个编译时的异常那么写为:

   public static int test(int a,int b) throws Exception {//使用 throws 告知此方法会抛出那些异常,请调用方法处理
        if(b==0)
            throw new Exception("除数为零");
        return a/b;
    }

该异常会返回到调用的地方,那么调用的一方必须对该异常进行处理
如果说不同的分支会抛出不同的异常,那么必须在方法中都需要注明

 public static void test(int a,int b) throws ArithmeticException,ClassCastException {//多个异常用逗号隔开
        if(b==0)
            throw new ArithmeticException();
        else throw new ClassCastException();      
    }

(2)捕获异常

捕获之后程序继续执行,如果没有被捕获那么程序就会终止
如果是多个,可以继续往下写,类似于 if…else…

try{

}catch(....){

}

实例:

public class t1 {
    public static void main(String[] args) {
        try{
            int res=divi(1,0);
            System.out.println(res);
        }catch (Exception e){
            System.out.println("捕获的异常信息为:"+e.getMessage());
        }
        System.out.println("程序继续执行");
    }
    public static int divi(int a,int b){
        int res=a/b;
        return res;
    }
}

运行结果:在这里插入图片描述

注意:(如果抛出多个异常,并且分情况讨论的话,并且相对异常父类在前的话,所以多个情况的要注意捕获的循序)

  • 抛出异常的子类会被其异常的父类捕获

如果多个异常一起打包处理的话,也可写为:

public class t1 {
    public static void main(String[] args) {
        try{
            int res=divi(1,0);
            System.out.println(res);
        }catch (ArithmeticException | NegativeArraySizeException e){
            System.out.println("出现了异常");
        }
        System.out.println("程序继续执行");
    }
    public static int divi(int a,int b){
        int res=a/b;
        return res;
    }
}

finally语句块中:放的是不管问题异常是否产生 都要执行的代码code。

try{
	...
}finally{
	...//无论异常是否产生 都要执行
}

//或者
try{
	...
}catch{
	...
}finally{
	...//无论异常是否产生 都要执行
}

(3)自定义异常(对异常的方法重写)

2、工具类(Java API)

(1)数学类

Math.abs();
Math.max();
	.
	.
	.
	.
	.
Math.log();// 默认 ln
Math.log10();//以10为底
//其他的用换底公式
Math.log(a)/Math.log(b);//以 b 为底 a 的对数

Math.ceil();//向上取整,不是四舍五入
Math.floor();//向下取整,不是四舍五入

(2) 数组类

int[] arr1,arr2;
Arrays.toString(数组名);//打印数组,结果形式:[1,2,3,4]
Arrays.deepToString(数组名);// 打印多维数组 结果形式:[[1,2,3,4],[1,2,3,4]]
Arrays.sort(数组名);// 从小到大排序,对浮点也可 无返回值
Arrays.fill( 数组名 , 赋值为多少); // 无返回值
Arrays.copyOf(赋值的数组 , 复制多少个 ); // 返回拷贝的数组
Arrays.copyOfRange(赋值的数组 , a , b ); //  返回拷贝的数组 区间[a,b)  下表为零开始计数
System.arraycopy(arr1 , s , arr2 , s1 , len);//无返值 从 arr1 中下表为 s 位置拷贝,到 arr2 下表为 s1 开始,拷贝了 len 个
Arrays.binarySearch(arr1 , 8);//二分查找有序数组 arr1 中值为 8 的下标,不存在返回 -1

Arrays.equals(arr1,arr2);// 一维数组 比较内容
Arrays.deepEquals(arr1,arr2);// 二维数组 比较内容

(3)字符串类

String str="fasdf";
String str1="fs";
String str2=new String();// 也可以直接 new 一个字符串 
 
str.indexOf('x'); // 返回 字符 或 字符串 在 str 中的第一个位置
str.lastIndexOf('x'); // 返回 字符 或 字符串 在 str 中的最后一个位置
str.charAt(3); // 返回当前位置的 字符

str.equals(str1); // 比较 str 和 str1 的内容是否相同 返回 Boolean
str.isEmpty(); // 字符串如果为 0 返回true

str.toLowerCase(); // 全部转为小写
str.toUpperCase(); // 全部转为大写

str.toCharArray(); // 将 str 转为 char 数组,并返回 char 数组,应赋值(可以直接复赋值)给一个 char 数组
str.getBytes(); // 将 str 转为 byte 数组 ,和 char 数组用法一样
str.substring(l,r); // 返回 [l,r) 区间内的字符串,如果不写 r 则会从 l 到末尾

str.trim(); // 去掉当前字符串的首位空格.


Stringfinal 类型的,所以一旦创建,其长度和内容是不可以改变的,他是一个常量
因此可以用 StringBuffer 类(也称字符串缓冲区)来操作字符串,他的长度和内容可以改变

StringBuffer str=new StringBuffer(); // 如果没用 new 一个对象的话,那么初始创建容量为 16, 缓冲区内不含任何内容
        // 也可以直接 new 一个空间,即 new 里面是数字,缓冲区内不含任何内容
        // 也可以直接 new 一个对象,缓冲区内是该对象,容量为 该对象的长度+16

str.length(); // 获取缓冲区的内容长度
str.capacity(); // 获取缓冲区的当前的容量
str.toString(); // 获取缓冲去的字符

str.append('c'); // 将参数添加到字符串中,无返回值
str.setCharAt(pos,'f'); // 修改指定索引位置的内容

str.insert(pos,"fd"); // 在 pos 的位置插入 “fd" ,无返回值
str.delete(pos); // 移除 pos 位置的字符,无返回值
str.delete(l,r); // 移除区间内字符 [ l, r )
str.reverse(); //反转字符串

StringBufferStringBuilder 基本相同
但是:

  • StringBuffer 是线程安全的, StringBuilder不是,即:如果没要求线程安全,且操作大量的字符串,用 StringBuilder更快
  • equals() 对这两种不能用,可以这样:str1.toString().equals(str2.toString())
  • 这两种不能直接用 + 连接两个字符串

(4)System 类和 Runtime 类

System.exit(); // 若参数为 0 则表示异常终止

System.gc(); // 回收垃圾

 System.currentTimeMillis(); // 返回的是当前时间与 1970年1月1日0:00 的时间差,单位 ms

getProperties()getProperty() 方法

import java.util.Enumeration;
import java.util.Properties;

public class fsd {
    public static void main(String[] args) {

        Properties properties=System.getProperties(); // 获取当前系统属性

        Enumeration enumeration=properties.propertyNames(); // 获取所有系统属性的键

        while(enumeration.hasMoreElements()){
            String key= (String) enumeration.nextElement(); // 获取系统属性的键

            String value=System.getProperty(key); // 获取当前的键值
            System.out.println(key+" ++++++  "+value);
        }
    }
}
Runtime rt=Runtime.getRuntime(); // 创建 Runtime对象
rt.exec(); // 参数为指定的可执行文件的路径
rt.freeMemory(); // 返回java虚拟机的空闲内存量,以字节为单位
rt.maxMemory(); // 返回Java虚拟机的最大可用内存量,以字节为单位
rt.availableProcessors(); // 返回java虚拟机的处理器个数
rt.totalMemory(); // 返回Java虚拟机的内存总量 ,以字节为单位
public class fsd {
    public static void main(String[] args) throws Exception {

        Runtime rt=Runtime.getRuntime(); // 创建 Runtime对象
        Process process=rt.exec("notepad.exe"); // 打开记事本 ,得到一个 表示进程的 Process 对象
        Thread.sleep(1000); // 休眠 1s
        
        process.destroy(); // 销毁进程
    }
}

(5)Random类


Random random = new Random(); // 以时间为种子,每次产生的随机数不同

int a = random.nextInt(100); // [0,100)以内的整数

// 还可以有 nextDouble()  nextFloat() nextBoolean() 等  
// 不写参数生成的是该类型的随机数
 
Random random = new Random(12);//设置指定种子,使得每次的随机数都相同

(6)BigInteger 类和 BigDecimal 类


如果需要定义一个超出int类型的整型数据,可以使用BigInteger 类的对象接收数据

BigInteger(String val)  将字符串 val 变为  BigInteger 类型的数据

BigInteger integer=new BigInteger("123");
BigInteger integer1=new BigInteger("345");

integer.add(integer1); // 计算和
integer.subtract(integer1); //计算与 integer1 的差
integer.multiply(integer1); // 计算 积
integer.divide(integer1); // 计算与 integer1 商
BigInteger res[]=integer.divideAndRemainder(integer1); // 计算与 integer 的商,第一个位置为 商 ,第二个位置为 余数

BigDecimal 多用于数据精度高的地方,因为 doublefloat容易丢失精度、
用法和BigInteger基本一样,多了

BigDecimal d=BigDecimal.valueOf(0.99); // 可以将 double 类型的数转为 BigDecimal

(7)日期类

(8)包装类

不想写了转一下
正则表达式
Java正则表达式用法

3、I/O

在这里插入图片描述

(1)、File类

File(); 参数为路径,根据指定路径创建一个File对像,可以为2个参数,具体参考样例
File file = new File("E://test//Test.txt");

//可以写为

File parent = new File("E://test");
File file = new File(parent,"Test.txt");

常用方法

boolean te=file.exists();// 判断文件是否存在
boolean te=file.delete();// 如果删除文件成功则返回 true
boolean te=file.createNewFile();// 当前文件不存在时,创建一个新文件,成功返回true
boolean te=file.canWrite();// 判断文件是否可读,可读返回true
boolean te=file.isDirectory();//判断File对象是否是目录

String name=file.getName();// 返回文件的名字
String path=file.getPath();// 返回文件的路径(相对路径)
String patha=file.getAbsolutePath();// 返回绝对路径

long time=file.lastModified();// 返回文件的最后修改时间
long tie=file.length(); // 返回文件的字节长度

有时候需要用到一些临时文件:

File file=File.createTempFile("te",".txt");// 文件的名字和后缀
file.deleteOnExit();// 在推出虚拟机后自动删除

(2)字节流

FileInputStream是文件字节输入流
InputStream是字节输入流

前者是后者的子类

用法基本相同
1.

	 FileInputStream fileInputStream=new FileInputStream("te.txt");// 文件字节输入流
     int b=0;
     while((b=fileInputStream.read())!=-1){//每次读取一个字节,当等与-1 表示文件读取完毕,读取会返回一个0~255的整数
         System.out.println(b);
     }
   byte[] buf = new byte[1024];
   /**
     * 读取数据,读取缓冲区指定大小的数据
     * 返回实际读取字节的数量(长度),如果未读取到数据则返回-1
     */
    int len = - 1;
    //循环读取文件中的数据,当len的值为-1时表示读取结束
    while((len=fileInputStream.read(buf,0,buf.length))!=-1){
        /**
         * 将字节数组中的字节转换字符串
         * 指定转换的起始下标,及转换长度
         */

        String str = new String(buf,0,len);

        System.out.println(str);
    }

输出流OutputStream

void write(int b); // 写入一个字节
void write(byte[] b);// 写入指定的字节数组
void write(byte[] b,int off ,int len);// 从 off 开始的len字节写入 
void flush();// OutputStream 类的方法,刷新输出流,并强制写出所有缓冲的输出字节
void close();// 输入/输出 关闭输入/输出流

(3) 字符流

FileReader 输入流
FileWriter 输出流

int read();// 以字符为单位读取数据
int read(char cbuf[]); // 将数据读入char类型的数组,并返回数据长度
int read(char cbuf[],int star,int len); // 将数据读入char类型的数组,并返回数据长度,从star开始写len个
long transferTo(Writer out);// 将数据直接读入字符输出流 
void write();// 以字符为单位写入数据
void write(char cbuf[]);
void write(char cbuf[],int star,int len);
void wirte(String str); // 将String类型的数据写出
void wirte(String str,int star,int len);// 指定str的区间
void flush();// 只有输出流有
void close();
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值