本文最后更新于 2024-12-11 18:34:20
补充 1. 字符串比较==
比较两个对象的地址是否相等equals
比较两个对象的内容是否相等例如:
1 2 3 String a="fsd" ,b="fsafsdd" ; boolen od=a.equals(b);
一、基本格式
变量名
:由数字、字母、下划线、美元符号($)组成,不能以数字开头
二、数据类型 1、基本数据类型 整数型:short 、 int 、long、byte
浮点数:float 、double
字符型:char
布尔型:boolean
2、引用数据类型 类:class
接口:interface
数组 枚举:enum
注解:annotation
三、方法 1、方法 方法是一段可重复调用的代码。(类似于c++中的子函数)
1 2 3 4 修饰符 返回值类型 方法名(参数类型 参数名1 ,参数类型 参数名2. ...){ return 返回值; }
2、方法的重载 在同一个作用域中,方法名相同但参数个数或者参数类型不同的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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
作为方法的结束
1 2 3 4 5 6 7 8 9 10 11 12 13 class role { String name; public role (String name) { this .name=name; } }public class Main { public static void main (String[] args) { role stu=new role ("宁" ); } }
在定义了有参构造方法之后,无参的构造方法不能在访问,即代码
1 2 3 4 5 6 7 8 9 10 11 12 13 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
以及更低的访问权限修饰
四、数组 1 2 数据类型[] 数组名; 数组名=new 数据类型[长度];
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class Main { public static void main (String[] args) { int [] x; x=new int [100 ]; int [] y=new int []{元素,元素....}; int [] z={元素,元素..}; int u=x.length; } }
二维数组 :和一维基本相同
1 2 3 4 5 6 数据类型[][] 数组名=new 数据类型[行数][列数] 数据类型[][] 数组名=new 数据类型[行数][]
五、类和对象 1、类 类是对象的抽象,用于描述一组对象的共同特征和行为。 类中可以定义成员变量和成员方法。 成员变量用于描述对象的特征,也被称为对象的属性 成员方法用于描述对象的行为简称对象。
1 2 3 4 5 class 类名{ 成员变量; 成员方法; }
1 2 3 4 5 6 7 8 9 10 11 12 class student { string name; int age=30 ; string sex; void read () { int age=50 ; System.out.println("成员方法" ); } }
允许局部变量和成员变量同名,但此时,方法中的变量值为局部变量的值,上面age就是50
2、对象(类比结构体) 1 2 3 4 5 6 7 8 9 10 11 类名 对象名=null ; 对象名=new 类名(); 类名 对象名=new 类名(); 对象名.属性名 对象名.方法名
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 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
修饰,私有属性只能被本类访问 如果需要外界访问或修改,要提供公共的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 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 如代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 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
变量不仅作为成员变量,也作为的构造方法的形参,在使用时会产生错误,所以,将本类的成员变量name
用this.name
进行调用。
this
不仅可以调用本类的成员变量,也可以在本类中调用本类的成员方法、构造方法(不是必须,条件可以的话,也可不用写this
)
在调用构造方法的时候应注意:
只能在构造方法中调用其他的构造方法,不能在成员方法中调用构造方法
在构造方法中,使用this
调用其他构造方法是,必须位于第一行,且只能出现一次
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 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 ("宁" ); } }
2、static
用于修饰类的成员,如成员方法、成员变量、代码块等
如果在Java程序中用static
修饰属性,则该属性成为静态属性(也称全局属性),可以用类名直接访问
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 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" ; } }
图释:
注意:
3.super
当子类重写了父类的方法后,子类对象将无法访问父类中被重写的方法,为了解决该问题,super
便产生了
(1)使用super
访问父类的非私有属性或方法
1 2 super .属性super .方法(参数1 ,参数2. ....)
(2)使用super
调用父类中指定的构造方法
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 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
修饰的类不可以被继承,也就是这样的类不能派生子类
例如:
①
1 2 3 4 5 6 7 8 9 10 11 12 final class A { }class B extends A { }public class Main { public static void main (String[] args) { } }
②
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class A { public final void shout () { System.out.println("balabala" ); } }class B extends A { public void shout () { } }public class Main { public static void main (String[] args) { } }
③ final
修饰的变量不能修改,类似于C语言中的const
,并且用其修饰的时候,变量名字要全部大写例如声明全局变量:
1 public static final int AGE=89 ;
6、 instanceof (判断是否为接口)
判断一个对象是否是某个类(或接口)的实例
格式:
上述 “ 对像 ” 如果是指定类的实例对像,则返回true
否则返回false
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 package PACAK1;import javafx.scene.AmbientLight;class Animal { public void shout () { System.out.println("喵喵..." ); } }class Dog extends Animal { 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 (); 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)); } }
九、代码块 执行循序: 静态代码块 -> 构造代码块 -> 构造方法 普通代码块是在主类中第一的代码块,所以执行循序不包括该块
1.普通代码块
意思:就是直接在方法会语句中定义的代码块
错误事例:
1 2 3 4 5 6 7 8 9 10 11 public class Main { public static void main (String[] args) { { int age=10 ; System.out.println(age); } System.out.println(age); } }
正确事例:
1 2 3 4 5 6 7 8 9 10 11 public class Main { public static void main (String[] args) { { int age=10 ; System.out.println(age); } int age=10 ; System.out.println(age); } }
由单纯的{}
括起来的代码为普通代码块,可以对变量起到了作用域的限定作用
2.构造块
意思:在类中定义的代码块
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class role { String name; { System.out.println("构造代码块" ); } }public class Main { public static void main (String[] args) { role stu=new role (); } }
注意:
构造代码块与构造方法、成员属性、成员方法同级
在实例化对象的时候,构造块先于构造方法执行,这个构造代码块写到前面还是后面没有关系
每当实例化一个对象的时候,都会先执行构造代码块,然后才会执行构造方法
3.静态代码块
使用 static
修饰的代码块
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class role { static { System.out.println("静态代码块在此" ); } }public class Main { public static void main (String[] args) { } }
注意:
十、继承
继承是指在一个现有的基础类上构建一个新的类,构建的新类被称为子类,现有的类称作父类,用关键字extends
声明
1 2 3 4 5 6 7 8 class 父类名{ } class 子类名 extends 父类名{ }
注意:
子类虽然可以通过继承访问父类的方法和成员,但是只能访问public
和protected
修饰的成员和方法,对于private , default
修饰的成员和方法不能访问
类只允许
单继承,不允许
多继承,如:
1 2 3 4 class A { }class B { }class c extends A ,B{ }
1 2 3 4 class A { }class B extends A { }class C extends A { }
多层继承也是可以的,即一个类的父类可以在继承另外的父类,如:
1 2 3 4 5 6 7 class A { }class B extends A { }class C extends B { }
子类,父类的称呼是相对的,正如上面的:b 是 c 的父类,同时又是 a 的子类
十一、抽象类
定义一个类时,常常需要定义一些成员方法用于描述类的行为特征,但有写方法的实现是无法确定的,例如:定义一个 Animal
的父类,其中有shout()
方法(用于输出叫声),那么不同的子类(也就是不同的动物)对于shout()
方法的输出也就不同,那么父类中的shout()
方法就无法确定写法,于是abstract
关键字就诞生了
(1)抽象方法实现不需要写出方法体,例如:
1 abstract 返回值类型 方法名(参数1 ,参数2. ..);
(2)抽象类也必须用abstract
关键字修饰,语法格式:
1 2 3 4 5 6 7 8 abstract class 类名{ 属性; 访问权限 返回值类型 方法名(参数....){ } 访问权限 abstract 返回值类型 抽象方法名(参数); }
抽象类定义规则:
包含抽象方法的类必须是抽象类
声明抽象类和抽象方法必须用abstract
修饰
抽象方法只需要声明不需要实现
如果一个非抽象类继承了抽象类,那么,该类必须重写抽象类中的全部抽象方法
注意:
使用abstract
修饰的抽象方法不能使用private
修饰
十二、接口
是一种用来定义程序的协议,它用于描述类或结构的一组相关行为
来源:接口是由抽象类衍生的一个概念,并由此产生了一种编程逻辑,可以称这种编程方式为面向接口编程
面向接口编程
:将程序的不同的业务逻辑分离,以接口的形式对接
不同的业务模块。接口中不实现任何业务逻辑,业务逻辑由接口的实现类完成。当业务需求变更时,只需要修改实现类中的业务逻辑,而不需要修改接口中的内容,以减少需求变更对系统产生的影响
面向接口编程,思想类比: 鼠标,键盘等通过 USB 接口来连接计算机,如需更换只要拔掉当前的 USB 插口,换上新的即可
目的:克服单继承的限制,因为一个类只能有一个父类,而一个类可以实现多个接口,使用关键字interface
声明
语法格式:
1 2 3 4 5 6 [public ] interface 接口名 [extends 接口1 ,接口2. ..]{ [public ] [static ] [final ] 数据类型 常量名=常量; [public ] [abstract ] 返回值的数据类型 方法名(参数列表); [public ] static 返回值的数据类型 方法名(参数列表){ } [public ] default 返回值的数据类型 方法名(参数列表){ } }
语法 “ extends 接口1,接口2… ” 表示一个接口可以有多个父接口,父接口之间用逗号隔开
接口中变量默认使用public static final
进行修饰,即全局变量,抽象方法默认用public abstract
修饰
接口中无论使写不写访问权限,接口中方法的默认权限永远都是用public
修饰
接口本身不能实例化,只能通过接口实现类
的事例对象进行访问(抽象方法和默认方法),implements
关键字实现。实现类必须重写接口中所有的抽象方法
定义接口实现类语法:
1 2 3 修饰符 class 类名 implements 接口1 ,接口2. 。。。{ }
综合应用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 interface Animal { int ID=1 ; void shout () ; }interface Action { public void eat () ; }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.eat(); dog.shout(); } }
补注:
如果一个子类既要实现接口,又要继承抽象类,则可以写为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 修饰符 class 类名 extends 父类名 implements 接口1 ,接口2. 。。{ }interface B { }abstract A{ }class C extends A implements B { }
1 2 3 4 5 6 7 8 9 10 11 12 13 interface B { }interface A { }interface C extends A ,B{ }class D implements C { }
十三、多态
大意:不同类的对象在调用同一个方法时表现出来的多种不同行为 例如:定义了一个抽象类 animal
,在该类中定义了一个抽象方法shout
,那么,同过定义不同的类去继承animal
类,并且重写其中的shout
方法,这样就是实现了多态
十四、对象类型的转换
向上转型:子类对象 —-> 父类对象 向下转型:父类对象 —-> 子类对象
(1)、向上转型
对象可以调用子类重写父类的方法,这样当需要添加新功能时,只需要新增一个子类,在子类中对父类的功能进行拓展,而不用更改父类的代码
更改格式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Animal { public void shout () { System.out.println("喵喵..." ); } }class Dog extends Animal { 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 (); Animal an=dog; an.shout(); } }
注意:
转型后的父类an
无法调用Dog
中的eat()
方法,因为eat()
方法只在子类定义了
(2)、向下转型
向下转型一般是为了重新获得因向上转型而丢失的子类特性
格式:
1 2 父类类型 父类对象 = 子类实例; 子类类型 子类对象 = (子类)父类对象;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Animal { public void shout () { System.out.println("喵喵..." ); } }class Dog extends Animal { 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)、成员内部类
内部类可以访问外部类的所有成员、无论是何种访问权限(额。。。就是类中套类)
如果想要通过外部类访问内部类,则需要通过外部类创建内部类对象,格式:
1 2 外部类名 外部类对象 = new 外部类名() ; 外部类名.内部类名 内部类对象 = 外部类对象.new 内部类名() ;
(2)、局部内部类
:也称方法内部类。在某个局部范围定义的类,他和局部变量都是在方法中定义的,有效范围只限于方法内部
可以访问外部类的所有成员变量和成员方法 如果要在外部类中访问局部内部类的成员,只能在局部内部类的所属方法中创建局部内部类的对象,通过对象访问局部内部类的额变量和方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 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
关键字; 静态内部类只能访问外部类的静态成员
格式:
1 外部类名.静态内部类 变量名 = new 外部类名.静态内部类名() ;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 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 调用某个方法时、如果该方法的参数是接口类型
,那么在传参时,除了可以传入一个接口实现类,还可以传入实现接口的匿名内部类作为参数
为什么要使用匿名内部类? 在实际开发中,我们常常遇到这样的情况:一个接口/类的方法的某个实现方式在程序中只会执行一次,但为了使用它,我们需要创建它的实现类/子类去实现/重写。此时可以使用匿名内部类的方式,可以无需创建新的类,减少代码冗余
1 2 3 new 继承的父类或实现的接口名{ 匿名内部类的类体 }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 interface animal { void show () ; }public class t1 { public static void main (String[] args) { animalopa(new animal () { @Override public void show () { System.out.println("miao..." ); } }); } public static void animalopa (animal an) { an.show(); } }
拓展: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 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
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Override 注解是伪代码,用于表示被标注的方法是一个重写方法。@Override 注解,只能用于标记方法,并且它只在编译期生效,不会保留在class文件中。@Override 检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。@Override 注解标记的方法声明,如果没有覆写或者实现超类(被继承的类)的方法声明,或者不是覆写Object的public 方法,那么编译就会报错。 使用@Override 注解,有助于我们尽早发现这样的错误:本来想声明一个“覆写”方法,却偶然声明成“重载”方法。 使用@Override 注解主要有两个好处:1 )帮助自己检查是否正确的重写父类方法2 )明显的提示看代码的人,这是重写的方法
拓展: Lambda表达式
:只有一个带实现的抽象方法时,匿名内部类可以用Lambda表达式
表示,可以存在其他方法,其他方法必须用default
修饰
1 2 3 4 5 6 7 8 9 10 11 12 13 14 interface Animal { void show () ; }public class t1 { public static void main (String[] args) { Animal stu=()->{ System.out.println("lambda方法" ); } ; stu.show(); } }
如果说show()
有参数:
1 2 3 4 5 6 7 8 9 10 11 12 13 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()
只有一个参数: 也可写为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 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 ); } }
如果说,方法体中只有一个返回语句
还可以在简化:
1 2 3 4 5 Animal stu=u->{ return u+"fsd" ; } ; Animal stu=u-> u+"fsd" ;
还可以用下面的方式重写方法: 第一种:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 interface Animal { String show (int u) ; }public class t1 { public static void main (String[] args) { t1 a=new t1 (); Animal animal=a::shoow; System.out.println( animal.show(2 )); } public String shoow (int p) { return "fsad" ; } }
第二种:(函数库自带的可以用)
1 2 3 4 5 6 7 8 9 10 11 12 13 interface Animal { int sum (int a,int b) ; }public class t1 { public static void main (String[] args) { Animal animal=(a,b)->Integer.sum(a,b); System.out.println( animal.sum(8 ,2 )); } }
==== ==== 一、异常
:在程序运行时可能出现的错误或非正常情况
1.系统错误(Error) 2.编译时异常(Exception)
1.运行时异常(RuntimeException)
(1)抛出异常
当调用某个方法的时候 ,如果跟传入错误的参数,那么程序将无法继续运行,这个时候我们可以手动抛出一个异常来终止程序运行下去,同时告知上一级方法执行出现了问题
throw
和 throws
区别:
1 2 3 4 5 6 7 8 9 10 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 ("除数为零" ); return a/b; } }
运行结果: 如果说抛出了一个编译时的异常那么写为:
1 2 3 4 5 public static int test (int a,int b) throws Exception { if (b==0 ) throw new Exception ("除数为零" ); return a/b; }
该异常会返回到调用的地方,那么调用的一方必须对该异常进行处理 如果说不同的分支会抛出不同的异常,那么必须在方法中都需要注明
1 2 3 4 5 public static void test (int a,int b) throws ArithmeticException,ClassCastException { if (b==0 ) throw new ArithmeticException (); else throw new ClassCastException (); }
(2)捕获异常
捕获之后程序继续执行,如果没有被捕获那么程序就会终止 如果是多个,可以继续往下写,类似于 if…else…
实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 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; } }
运行结果:
注意:(如果抛出多个异常,并且分情况讨论的话,并且相对异常父类在前的话,所以多个情况的要注意捕获的循序)
如果多个异常一起打包处理的话,也可写为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 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。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 try { ... }finally { ... }try { ... }catch { ... }finally { ... }
(3)自定义异常(对异常的方法重写) 2、工具类(Java API) (1)数学类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Math.abs(); Math.max(); . . . . . Math.log(); Math.log10(); Math.log(a)/Math.log(b); Math.ceil(); Math.floor();
(2) 数组类 1 2 3 4 5 6 7 8 9 10 11 12 13 int [] arr1,arr2; Arrays.toString(数组名); Arrays.deepToString(数组名); Arrays.sort(数组名); Arrays.fill( 数组名 , 赋值为多少); Arrays.copyOf(赋值的数组 , 复制多少个 ); Arrays.copyOfRange(赋值的数组 , a , b ); System.arraycopy(arr1 , s , arr2 , s1 , len); Arrays.binarySearch(arr1 , 8 ); Arrays.equals(arr1,arr2); Arrays.deepEquals(arr1,arr2);
(3)字符串类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 String str="fasdf" ; String str1="fs" ; String str2=new String (); str.indexOf('x' ); str.lastIndexOf('x' ); str.charAt(3 ); str.equals(str1); str.isEmpty(); str.toLowerCase(); str.toUpperCase(); str.toCharArray(); str.getBytes(); str.substring(l,r); str.trim();
String
是 final
类型的,所以一旦创建,其长度和内容是不可以改变 的,他是一个常量 因此可以用 StringBuffer
类(也称字符串缓冲区)来操作字符串,他的长度和内容可以改变
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 StringBuffer str=new StringBuffer (); str.length(); str.capacity(); str.toString(); str.append('c' ); str.setCharAt(pos,'f' ); str.insert(pos,"fd" ); str.delete(pos); str.delete(l,r); str.reverse();
StringBuffer
和 StringBuilder
基本相同 但是:
StringBuffer
是线程安全的, StringBuilder
不是,即:如果没要求线程安全,且操作大量的字符串,用 StringBuilder
更快
equals()
对这两种不能用,可以这样:str1.toString().equals(str2.toString())
这两种不能直接用 +
连接两个字符串
(4)System 类和 Runtime 类 1 2 3 4 5 6 System.exit(); System.gc(); System.currentTimeMillis();
getProperties()
和 getProperty()
方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 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); } } }
1 2 3 4 5 6 Runtime rt=Runtime.getRuntime(); rt.exec(); rt.freeMemory(); rt.maxMemory(); rt.availableProcessors(); rt.totalMemory();
1 2 3 4 5 6 7 8 9 10 public class fsd { public static void main (String[] args) throws Exception { Runtime rt=Runtime.getRuntime(); Process process=rt.exec("notepad.exe" ); Thread.sleep(1000 ); process.destroy(); } }
(5)Random类 1 2 3 4 5 6 7 8 9 Random random = new Random (); int a = random.nextInt(100 ); Random random = new Random (12 );
(6)BigInteger 类和 BigDecimal 类
如果需要定义一个超出int
类型的整型
数据,可以使用BigInteger
类的对象接收数据
1 2 3 4 5 6 7 8 9 10 BigInteger(String val) 将字符串 val 变为 BigInteger 类型的数据 BigInteger integer=new BigInteger ("123" ); BigInteger integer1=new BigInteger ("345" ); integer.add(integer1); integer.subtract(integer1); integer.multiply(integer1); integer.divide(integer1); BigInteger res[]=integer.divideAndRemainder(integer1);
BigDecimal
多用于数据精度高的地方,因为 double
和float
容易丢失精度、 用法和BigInteger
基本一样,多了
1 BigDecimal d=BigDecimal.valueOf(0.99 );
(7)日期类 (8)包装类 不想写了转一下 正则表达式 Java正则表达式用法
3、I/O
(1)、File类 1 File(); 参数为路径,根据指定路径创建一个File对像,可以为2 个参数,具体参考样例
1 2 3 4 5 6 File file = new File ("E://test//Test.txt" );File parent = new File ("E://test" );File file = new File (parent,"Test.txt" );
常用方法
1 2 3 4 5 6 7 8 9 10 11 12 boolean te=file.exists();boolean te=file.delete();boolean te=file.createNewFile();boolean te=file.canWrite();boolean te=file.isDirectory(); String name=file.getName(); String path=file.getPath(); String patha=file.getAbsolutePath();long time=file.lastModified();long tie=file.length();
有时候需要用到一些临时文件:
1 2 File file=File.createTempFile("te" ,".txt" ); file.deleteOnExit();
(2)字节流 FileInputStream
是文件字节输入流 InputStream
是字节输入流
前者是后者的子类
用法基本相同 1.
1 2 3 4 5 FileInputStream fileInputStream=new FileInputStream ("te.txt" ); int b=0 ; while ((b=fileInputStream.read())!=-1 ){ System.out.println(b); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 byte [] buf = new byte [1024 ]; int len = - 1 ; while ((len=fileInputStream.read(buf,0 ,buf.length))!=-1 ){ String str = new String (buf,0 ,len); System.out.println(str); }
输出流 (OutputStream
)
1 2 3 void write (int b) ; void write (byte [] b) ;void write (byte [] b,int off ,int len) ;
1 2 void flush () ;void close () ;
(3) 字符流 FileReader
输入流FileWriter
输出流
1 2 3 4 int read () ;int read (char cbuf[]) ; int read (char cbuf[],int star,int len) ; long transferTo (Writer out) ;
1 2 3 4 5 6 7 void write () ;void write (char cbuf[]) ;void write (char cbuf[],int star,int len) ;void wirte (String str) ; void wirte (String str,int star,int len) ;void flush () ;void close () ;