博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java 函数、类、接口、泛型、对象、异常处理、lambda表达式
阅读量:2419 次
发布时间:2019-05-10

本文共 7803 字,大约阅读时间需要 26 分钟。

目录

 

函数

  • 递归函数:在方法体内调用方法本身,方法要有出口。
  • 函数重载:同一个类中,方法名相同,形参表不同(数据类型、参数个数),与返回值类型、修饰符无关。
  • 个数可变的参数:放在形参表末尾,调用时该位置可传入0个或多个指定类型的参数,实质是以数组方式传入,在函数体中以数组方式进行操作。
public void test(String str, String... args) {
//jvm会预先创建一个数组来接收个数可变的参数,即使传了0个参数,args也不为null //可根据数组的元素个数来判断是否传入了参数 if(args.length!=0){
for (String arg : args) {
//... } }}
  • 传参方式:java只有一种传参方式——传值,把实参的值拷贝一份传给形参。拷贝使用的是浅拷贝,基本数据类型、String拷贝的是其中的数值常量、字符串常量,修改形参不会影响到实参;引用类型拷贝的是对象引用,形参、实参指向同一个对象,修改形参就是修改实参。

 

类、内部类、抽象类

面向对象的3大特性:封装、继承、多态

 

继承

在子类的构造函数中,可以

super(xxx);   //调用父类带参的构造函数,必须放在方法体的第一行

如果在构造函数中没有显式调用父类的构造函数,会在执行构造函数之前自动调用父类无参的构造函数。

 

重写父类的方法

  • 方法名相同、形参表相同
  • 如果父类方法是类方法(static)| 实例方法,子类方法也要是static | 实例方法,与父类保持一致
  • 子类方法的返回值类型要 <= 父类方法的返回值类型
  • 子类方法抛出的异常类型要 <= 父类方法抛出的异常类型
  • 子类方法的访问权限要 >= 父类方法的访问权限(如果父类方法使用private修饰,则子类不会继承该方法,也就不能重写)
     

在子类中访问父类的成员

super(xxx)  //调用父类的构造函数super.xxx   //访问父类的成员变量(要有权限才可以)super.xxx(xxx)  //调用父类的成员方法

 

创建对象时,会先初始化这个类所有的父类。

 

多态

引用型变量有2个类型:编译时类型、运行时类型。

编译时类型是声明该变量时的类型,运行时类型是实际赋给该变量的类型。

多态:运行时类型可以不一致。

 

public void f(User user) {
}

编译时类型是User,假设User有2个子类Student、Teacher,运行时可以传入Student、Teacher类的对象,类型不一致,即多态。

 

判断某个引用型变量是否是某个类 | 接口的实例

User user = new User();if(user instanceof User){
//返回boolean值}

变量 instanceof 类 | 接口名,变量要声明为该类|接口类型,否则通不过编译。

 

内部类

类中可以嵌套其它类

class Outer {
//...... class Inner {
//....... } }

 

匿名内部类没有类名,只能使用一次,用来实现接口、抽象类,会在该处创建匿名内部类的一个实例

new 接口|抽象类{
}

 

抽象类

public abstract class Xxx {
//..... public abstract String Xxx();}
  • 抽象类使用abstract修饰,不能创建实例,是用来被继承、重写的。
  • 抽象方法使用abstract修饰,没有方法体。
  • 抽象类中可以不含抽象方法,但如果类中有抽象方法,该类必须声明为抽象类。

 

枚举

枚举常用于表示同一种类的常量集合,比如订单状态、用户角色、职称等。

 

以前的方式

public class Role {
public static final String COMMON = "common"; public static final String VIP = "vip"; public static final String SVIP = "svip";}

 

枚举

//成员变量+私有构造器+getter方法public enum Role {
//实质是调用构造函数创建当前类的实例,作为类的静态成员 COMMON("common"), VIP("vip"), SVIP("svip"); private String role; private Role(String role) {
this.role = role; } public String getRole() {
return this.role; }}//可以不设置成员变量public enum Role {
COMMON, VIP, SVIP;}

 

枚举在编译后会产生一个.class文件,使用javap反编译.class文件得到的java代码如下

public final class Role extends Enum
{
public static final Role COMMON; public static final Role VIP; public static final Role SVIP; public static Role[] values(); public static Role valueOf(String); public String getRole(); static {
}}
  • 编译时会把枚举替换成一个对应的类,且使用final修饰,不能被继承。
  • 枚举对对应的类会继承抽象类Enum,java中的类只支持单继承,不能再继承其它类。
  • 枚举实例会以类的实例的形式做为类的静态成员,使用static final修饰。

 

接口

  • 类是对实例的抽象,抽象类、接口是对类的抽象。
  • 接口定义程序设计规范,本身并不提供任何实现,体现了规范(设计)、实现分离的设计方式。
public interface Xxx {
// 成员变量默认使用public static final修饰,即常量,在声明时就必须指定初始值 String XXX = ""; // 方法默认使用public abstract修饰 String xxx(); // 可以定义默认方法,但必须要有方法体 default void test2() {
} //接口中可以定义静态方法方法,但必须要有方法体,默认使用(也只能使用)public修饰 static void test3() {
} // 内部也可以定义类、接口、接口,均默认使用(也只能使用)public static修饰 // 不能有构造函数、初始化块、私有方法}

 

// 类只支持单继承,接口支持多继承class 类A extends 类B {
}interface 接口A extends 接口B, 接口C {
}// 一个类可以实现多个接口class 类A implements 接口A, 接口B {
}// 类在继承的同时可以实现接口class 类A extends 类B implements 接口A, 接口B {
}

 

接口、抽象类的区别

  • 接口中只能定义常量、方法,不能表达对象状态的变化(常量不可变);抽象类中可以定义对象的成员字段,可以表达对象状态的变化。
  • 接口中的方法的访问权限都只能是public,抽象类则无此限制。
  • 类可以同时实现多个接口,但不能同时继承多个类。

一般把子类共有的成员变量、实现相同的公共方法抽象出来放在抽象类中,实现不同的公共方法也可以作为抽象方法放在抽象类中;子类中公共的常量,以及实现不同的公共方法,可以放在接口中。

 

泛型

泛型可以限制对象|元素类型,在编译时对数据类型进行校验。

//在普通的成员变量中使用泛型public class Test
{
private T t; public Test(T t) {
this.t = t; } public T getT() {
return t; } public void setT(T t) {
this.t = t; } }
//静态成员字段不能使用泛型,但静态方法的返回值类型、参数类型可以使用泛型class Test {
//需要在返回值类型前用< >进行声明 public static
T test(T t) {
return t; } }
//类名后面标注的泛型可以用extend指定上边界,但不能用super指定下边界public class Test
{
}//可以使用多个泛型public class Test
{
}public class Test
{
//使用泛型声明变量、返回值类型时,可以用? extend指定上边界,必须要是Number的子类 public Test
handler1(Test
test) {
return test; } //可以用? super声明下边界,必须要是Integer的父类 public void handler2(Test
test) {
} //上边界、下边界都包含边界本身 }

 

注意点

  • 泛型不能使用int、float等基本类型
  • 编译时会擦除泛型,生成的字节码中没有泛型。
  • 对于同一个类,不管使用哪种泛型,都是同一个类,getClass()获取到的都是同一个Class对象,实例都属于同一个类。
  • 静态成员变量不能使用泛型,是因为类加载时会初始化静态成员,如果使用泛型则不能确定数据类型,无法赋初值。

 

创建对象的4种方式

1、使用new关键字调用构造方法,可调用任意构造方法。

 

2、通过反射创建实例

  • 可以使用class对象的newInstance()方法,但只能调用无参的构造方法,且该类中需要提供无参的构造方法。
  • 也可以先获取要使用的构造方法,借助Constructor类的newInstance方法创建实例,可以调用任意构造方法。

实质都是调用构造方法创建实例。

try {
//实质是调用无参构造器创建实例 User user = User.class.newInstance();} catch (InstantiationException e) {
e.printStackTrace();} catch (IllegalAccessException e) {
e.printStackTrace();}
try {
//通过class对象获取要使用的构造器,通过构造器创建实例 Constructor
noArgConstructor = User.class.getConstructor(); User user1 = noArgConstructor.newInstance(); Constructor
allArgConstructor = User.class.getConstructor(Integer.class, String.class, String.class); User user2 = allArgConstructor.newInstance(1, "chy", "188xxxxxx");} catch (NoSuchMethodException e) {
e.printStackTrace();} catch (InvocationTargetException | InstantiationException | IllegalAccessException e) {
e.printStackTrace();}

 

3、使用对象的clone()方法创建实例,需要重写Object类的clone()方法

@Data@AllArgsConstructor@NoArgsConstructorpublic class User {
private Integer id; private String name; private String tel; /** * Object类的clone()方法是直接抛出异常 CloneNotSupportedException * 需要重写Object类的clone()方法,把访问权限改为public,可以把返回值类型改为具体类型,避免使用时强转 */ @Override public User clone() {
User user = new User(); user.setId(this.id); user.setName(this.name); user.setTel(this.tel); return user; }}
User user = new User(1, "chy", "188xxxxx");User user1 = user.clone();

 

4、使用反序列化创建对象,前提是该类要是可序列化的,比如implements Serializable。

 

前2种实质都是调用构造方法创建实例,后2种则不是。

 

异常处理

java的异常体系

在这里插入图片描述

  • java中的异常分为Error、Exception,Error是程序本身处理不了的异常,Excepttion是程序本身可以处理的异常。
  • Exception分为CheckedException编译时异常、RuntimeException运行时异常。

 

try{
int i = 1 / 0;}catch (Exception e){
System.out.println("catch...");}finally {
System.out.println("finally...");}System.out.println("other...");

try中没有发生异常:try -> finally -> finally之后的代码

try中发生了异常:

  • 不再执行try中后续的代码,转到执行catch
  • 如果catch中直接处理完了异常,则执行finally -> finally之后的代码;如果catch中throw往外抛了异常,则不再执行catch中后续的代码,直接执行finally,执行finally后不会再执行finally块之后的代码,而是跳到外层的catch中捕获处理异常(如果有外层的异常处理)。

 

在方法体中没有捕获处理异常,会跳出该方法的栈帧,导致方法体中后续代码都不会执行。

在循环体中,慎用throw直接抛出异常,如果循环体中的异常直接抛到了循环体外,会导致循环终止,后续批次都不会执行。

比如使用循环批量推送短信,某次循环时发生异常,没有在循环内处理异常,让异常抛到了循环外,则循环会被终止,循环中后续批次的消息都不会发送。

循环这种批量操作的场景,往往要尽量避免循环被异常终止,保证循环的继续执行,在循环体中可能发生异常的地方使用try…catch捕获处理掉异常。

 

可以extends Exception实现自定义的异常类。

 

final关键字

final可修饰类、变量(包括成员变量、局部变量)、方法

  • 被final修饰的类不能被继承
  • 被final修饰的变量,声明时就必须赋值,后续不能修改其值,即只读。基本类型、String类型不能改变值,引用类型不能修改引用(内存地址),但可以修改引用指向的对象本身。
  • 被final修饰的方法不能被重写

 

初始化块

初始化块和成员变量、成员函数一个级别,一般用于初始化。

class Xxx {
// 普通初始化块 {
} // 静态初始化块 static {
} // ......}

一个类中可以有多个初始化块,如果都是static初始化块或者普通初始化块,越靠前的越先执行。

static初始化快只能访问类的静态成员,只在JVM加载类的class对象时执行1次,常用于初始化类的静态成员、公共资源。

编译时,会把普通初始化块中的代码放到构造函数函数体内的最前面。每次创建对象时,在执行构造函数之前,都会先执行普通初始化快。普通初始化快常用与初始化对象。

 

lambda表达式

函数式接口:接口中的抽象方法有且只有1个。可以有其它成员,但抽象方法必须要有且只能有1个。

lambda表达式是函数式接口的匿名内部类实现的语法糖,可以代替函数式接口的匿名内部类,只能代替函数式接口的匿名内部类,不能代替其它的匿名内部类。

@FunctionalInterface   //声明为函数式接口interface FI {
void out(String str1,String str2);}class T{
// lambda表达式 private FI fi = (str,str2) -> {
//参数表直接写参数名,不写类型 System.out.println(str + " " + str2); }; }

lambda表达式用于实现函数式接口、并在该处创建一个实例,和匿名内部类相似,但匿名内部类可以实现任何抽象类、接口,lambda表达式只能实现函数式接口。

 

lambda表达式语法

(形参表) -> {
//形参表不写参数类型,直接写参数名  //......}

lambda表达式其实就是函数式接口中抽象方法的实现。

只有一个形参时,可以缺省();函数体只有一条语句,且该语句是return语句时,可以缺省{ }、关键字return。

转载地址:http://egqlb.baihongyu.com/

你可能感兴趣的文章
研发团队来了高颜值的妹子,这结局万万没想到 | 每日趣闻
查看>>
太难了!开源项目如何商业化?
查看>>
谷歌排名第一的编程语言,死磕它这两点,小白也能学的会!不信你看!
查看>>
程序员掉头发的原因找到了 | 每日趣闻
查看>>
腾讯:我就是那只吃了假辣椒酱的憨憨。老干妈:企鹅你可长点心吧!
查看>>
倒计时1天 | 张钹院士领衔,AI开发者大会20大论坛全攻略!
查看>>
运维工程师的日常?? | 每日趣闻
查看>>
31 道 Java 核心面试题,统统打包给你!
查看>>
太拼了:谷歌第一编程语言小白也能学会!
查看>>
三分钟黑了阿里?马云下死命令留他?吴翰清辟谣:我没黑过阿里
查看>>
如果重新一次高考,你还会选择软件专业当程序员吗? | 每日趣闻
查看>>
如何设计一个安全可靠的 API 接口?
查看>>
一年一度程序员“补课”季来袭,618 背后技术大公开!
查看>>
我和美国 AI 博士聊了聊:2020 年,这件事比存钱更重要!
查看>>
陈芳,高考之后我要学计算机专业,将来做 IT 发财了,我就娶你!
查看>>
“编程能力差的程序员,90%输在这事上!”谷歌AI专家:都是瞎努力!
查看>>
张一鸣做电商:再造一个“抖音”
查看>>
“你写的 Bug 让我来改好吗” | 每日趣闻
查看>>
大厂技术文档:Redis+Nginx+Spring全家桶+Dubbo精选
查看>>
笑死,别再黑程序员了好吗? | 每日趣闻
查看>>