Java 修饰符详解:吐血整理,带你从底层语法和开发案例疏通这 11 种常见修饰符

简介: Java 修饰符详解:吐血整理,带你从底层语法和开发案例疏通这 11 种常见修饰符

文章目录


前言

在 Java 的语言体系中共有 11 种常见的修饰符,其在我们日常的开发中一般有四种使用情况:成员变量、成员方法、代码块和内部类,那么在应用过程中我们还应该具体注意些什么?通过本文中我们将从最基础的底层和原理来理解和疏通这些常见修饰符语法说明以及在常见的开发中如何使用。

image.png


一、11 种常见的 Java 修饰符

1.1、修饰符应用表

修饰符 构造方法 方法 数据 解释
(default) 类、构造方法、方法或数据域在所在的包中可见
public 类、构造方法、方法或数据域在任何包任何程序中都可见
private 构造方法、方法或数据域只在所在的类中可见
protected 构造方法、方法或数据域在所属的包中可见,或者在任何包中该类的子类中可见
static 定义类方法、类数据域或静态初始化模块
final 终极类不能扩展。终极方法不能在子类中修改。终极数据域是常量
abstract 抽象类必须被扩展。抽象方法必须在具体的子类中实现
native 用native修饰的方法表明它是用Java以外的语言实现的
synchronized 同一时间只有一个线程可以执行这个方法
strictfp 使用精确浮点数计算模式,保证在所有的Java虚拟机中计算结果都相同
transient 标记实例数据域,使其不进行序列化

1.2、修饰符访问权限对比

public > protected > default > private

说明:以下仅介绍我们常用的 7 种修饰符语法说明以及开发应用说明,另外 4 种用法查看修饰符应用表即可。

二、public 修饰符

2.1、public 修饰符语法说明

  • 修饰类、方法、变量。
  • 可以在任意位置访问,公共的。

2.2、public 修饰符开发应用

  • 开发中,通常类和业务方法都使用 public 修饰。

三、private 修饰符

3.1、private 修饰符语法说明

  • 修饰方法、变量、还可以修饰内部类。
  • 只能在本类中访问,私有的。

3.2、private 修饰符开发应用

  • 开发中,通常实体类(Entity,Vo)中的成员变量使用 private 修饰,会提供访问这些变量的方法 getter 或 setter,原则上要求不准定义私有的方法。
  • 一个实体数据的表通常对应一个实体类。

四、protected 修饰符

4.1、protected 修饰符语法说明

  • 修饰方法、变量、还可以修饰内部类。
  • 同一个包可以访问、子类可以访问(子类和父类不在同一个包也可以访问)。

4.2、protected 修饰符开发应用

  • 开发中,通常方法或变量是用来继承的,都使用 protected 修饰。
  • 在继承中,方法的重写,子类方法的访问权限必须大于或等于父类方法的访问权限,举例代码如下:
class Fu {
  public void play() {
  }
}
class Son extends Fu {
  void play() {
  }
}

五、default 修饰符(不加任何访问权限修饰符)

说明:使用 default 修饰符与不加任何访问权限修饰符效果是一样的。

5.1、default 修饰符语法说明

  • 修饰类、方法、变量。
  • 只能在同一个包中访问,子类也必须在同一个包中。

5.2、default 修饰符开发应用

  • 项目中,类、方法、变量根据需求,通常都会指定访问权限。

六、static 修饰符

由于static 修饰符作用较多,我们对其拆开进行逐步分析。

6.1、类(静态)变量与实例变量

  • 类变量:被存储在方法区中,“只有一份”,被所有对象共享。当类被加载的时候,立即被存储在方法区中,当类被卸载,类变量立即释放内存。
  • 实例变量:在创建对象之后,被分配到堆内存中,实例变量属于某个具体的对象。当创建对象,实例变量出现在堆内存中,当对象被垃圾回收,实例变量立即释放内存。

比如我们创建两个对象,代码如下:

Cell c1 = new Cell(4,5);
Cell c2 = new Cell(5,6);

当创建对象 c1,c2 时,实例变量(4,5),(5,6)出现在堆内存中,当对象 c1,c2 被垃圾回收,实例变量立即释放内存。

6.1.1、类(静态)变量与实例变量语法说明

  • Java 中 可以通过 static 关键字修饰变量达到全局变量的效果
  • static 修饰的变量(静态变量)属于类,在类第一次通过类加载器到 jvm 时被分配至方法区,所以我们也称其为类变量。

image.png

  • 没有 static 修饰的变量,称为实例变量。

6.1.2、类(静态)变量与实例变量开发应用

  • 类变量可以由类名直接访问,开发中推荐使用类名的全称。

比如我们定义一个实体类,代码如下:

public class Student {
  // 实例变量,在创建对象之后,被分配到堆内存中,实例变量属于某个具体的对象
  // 当创建对象,实例变量出现在堆内存中,当对象被垃圾回收,实例变量立即释放内存
  String name;
  // 类变量,被存储在方法区中,"只有一份",被所有对象共享
  static String jtName;
  public void print() {
    System.out.println(this.name);
    System.out.println(jtName);
  }
}

下次使用静态变量 jtName 时,我们直接使用 Student 这个类名直接调用即可。

同时我们也就可以理解下面两个对象的属性取值是一样的,代码如下:

public class Demo01 {
  public static void main(String[] args) {
    // TODO Auto-generated method stub
    Student stu1 = new Student();
    stu1.name = "张三";
    stu1.jtName = "王老师";
    Student stu2 = new Student();
    // 一般直接取类名
    // stu2.jtName = "卢老师";
    Student.jtName = "卢老师";
    System.out.println(stu1.name);// 张三
    System.out.println(stu2.name);// null
    System.out.println(stu1.jtName);// 卢老师
    System.out.println(stu2.jtName);// 卢老师
  }
}

6.2、类(静态)方法与实例方法

  • 静态方法:static 修饰的方法属于类方法,不需要创建对象就可以调用。static 方法中不能使用 this 和 super 等关键字,不能调用非 static 方法,只能访问所属类的静态成员变量和静态方法。静态方法(类方法),当类被加载,静态方法立即被加载到方法区中,类方法可以由类名直接调用。
  • 实例方法:没有 static 修饰的方法,实例方法,当创建对象之后,实例方法立即被加载到方法区中,多个实例共享一份实例方法。

6.2.1、类(静态)方法与实例方法语法说明

  • 类方法中,不能使用 this 关键字,类方法中不隐含调用该方法对象的参数。
  • 实例方法可以直接调用静态方法,静态方法不可以直接访问实例成员,必须创建对象,由对象访问。
  • 所有对象共享的数据,定义为静态变量,否则定义为实例变量方法,方法中没有访问实例成员,可以定义为静态方法。

6.2.2、类(静态)方法与实例方法开发应用

  • 项目中,通常工具类中的方法,都是静态的。

6.3、static 静态代码段

6.3.1、static 静态代码段语法说明

  • JVM 在加载类时会执行 static 静态代码段,常用于初始化静态变量。
  • static 代码只会在类被加载时执行且执行一次。
  • 静态优于对象。

6.3.2、static 静态代码段开发应用

  • 开发中,通常用于加载静态资源,读取配置文件等操作,在静态代码段中实现。

比如我们定义一个工具类,代码如下:

public class SomeUtil {
  // 默认的无参构造
  public SomeUtil() {
    System.out.println("创建对象!");
  }
  // 静态优于对象
  // 静态代码段 当类被加载,立即被执行,一个类在同一个进程中,只加载一次
  static {
    System.out.println("加载静态资源!");
  }
  // 实例代码段
  {
    System.out.println("实例代码段!");
  }
  public static void do1() {
    System.out.println("do1....");
  }
  public static void do2() {
    System.out.println("do2....");
  }
  public static void do3() {
    System.out.println("do3....");
  }
  public static void main(String[] args) {
    SomeUtil.do1();
    SomeUtil.do2();
    SomeUtil.do3();
    SomeUtil s1 = new SomeUtil();
    SomeUtil s2 = new SomeUtil();
  }
}

执行 main 方法,根据输出的内容我们可以明确看出执行的顺序。静态代码段只执行一次,然后是静态方法被执行,最后是 new 的对象执行无参构造和实例代码段,new 一次执行一次。

同时也可以得出我们的结论:静态优于对象,如下图所示:

image.png

6.4、static 内部类

  • static 内部类可以不依赖外部类实例对象而被实例化,而内部类需要在外部类实例化后才能被实例化。
  • 静态内部类不能访问外部类的普通变量,只能访问外部类的静态成员变量和静态方法。

七、final 修饰符

7.1、final 修饰符语法说明

  • final 类,不能被继承。
  • final 方法,不能被重写。
  • final 修饰的变量,是常量。

7.2、final 修饰符开发应用

  • 开发中,我们使用 final 定义数据字典。

比如:在如下 Card 类中我们定义数据字典,用于 main 函数的输出和查询。

说明:数据字典是指对数据的数据项、数据结构、数据流、数据存储、处理逻辑等进行定义和描述,其目的是对数据流程图中的各个元素做出详细的说明,使用数据字典为简单的建模项目。简而言之,数据字典是描述数据的信息集合,是对系统中使用的所有数据元素的定义的集合。

举例使用 final 定义数据字典,代码如下:

public class Card {
  // 开发中,使用final定义数据字典。
  public static final int SPADE = 1;
  public static final int HEART = 2;
  public static final int BLACK = 5;
  public static final int FLOWER = 6;
  public static final int THREE = 0;
  public static final int EIGHT = 5;
  public static final int JACK = 8;
  public static final int QUEEN = 9;
  public static final int KING = 10;
  public static final int ACE = 11;
  public static final int DUCE = 12;
  public static final int JOKER = 13;
  private int suit;
  private int num;
  public Card() {
  }
  public Card(int suit, int num) {
    this.suit = suit;
    this.num = num;
  }
  public int getSuit() {
    return suit;
  }
  public void setSuit(int suit) {
    this.suit = suit;
  }
  public int getNum() {
    return num;
  }
  public void setNum(int num) {
    this.num = num;
  }
  public static void main(String[] args) {
    Card card = new Card(Card.HEART, Card.THREE);
    System.out.println(card.getNum());
  }
}

八、abstract 修饰符

8.1、abstract 修饰符语法说明

  • 抽象的,可以修饰类,修饰方法

修饰抽象类

  • 抽象类存在的意义在于被继承。
  • 抽象类不可以创建对象。
  • abstract 不能和 final 一起使用 。

修饰抽象方法

  • 抽象方法,只有定义没有实现。
  • 如果一个类中有抽象方法,这个类必须是抽象类。
  • 一个抽象类中,可以没有抽象方法。
  • 抽象类的子类,必须实现父类中所有的抽象方法。

8.2、abstract 修饰符开发应用

  • 抽象类中既可以有默认实现的方法,又可以有没有实现的方法。
  • 接口的适配器——用子类去实现接口中的方法。

九、接口(特殊的抽象类)

9.1、接口语法说明

  • 特殊的抽象类接口中的方法都是抽象方法,接口中的变量都是静态常量。
  • 定义接口使用 interface 关键字。
  • 实现接口使用 implements 关键字。
  • 类实现了接口,必须实现接口中所有的方法。

如下我们定义了一个接口 MyInterface,代码如下:

public interface MyInterface {
  // 接口是高一级别的抽象。不能被实例化,所以只能定义常量
  // 定义了变量需要实例化,赋值才能使用,跟接口违背
  // 特殊的抽象类 接口中的方法都是抽象方法 接口中的变量都是静态常量
  int I = 10;
  // 如果类中所有的方法都是抽象方法,使用接口
  void method1();
  void method2();
}

这里我们 MyImpClass 类实现了接口,就必须实现接口中所有的方法,代码如下:

import java.io.Serializable;
/**
 * 其实适配器只是一个类,它实现了某种接口,提供了方法体。 
 * 这样,再用到这个接口时,可以直接继承适配器,这样就不需要把接口中的每一个方法再填充一遍了。
 * 只需要在这个类中复写一下需要用的方法。这样简单,方便。
 * 
 * @author bailu
 *  */
public class MyImpClass implements MyInterface, Serializable {
  // Serializable序列化
  private static final long serialVersionUID = 1L;
  // 重写接口的方法——适配器,
  @Override
  public void method1() {
    System.out.println(I);
  }
  @Override
  public void method2() {
  }
}

9.2、接口开发应用

  • 如果类中所有的方法都是抽象方法,使用接口。
  • 接口是用来制定标准或规范。
  • 可以降低组件之间的耦合度,扩展组件的功能。
  • 体现了设计模式中的开闭原则。

9.3、抽象类和接口的区别是什么?

  • 抽象类中,可以定义抽象方法和非抽象方法。接口中,所有的方法都是抽象方法。
  • 一个类只能继承一个抽象类。一个类可以实现多个接口,多个接口使用逗号分隔。

如下的类既实现了接口 MyInterface,同时实现了 Serializable 序列化序列化,代码如下:

import java.io.Serializable;
/**
 - 其实适配器只是一个类,它实现了某种接口,提供了方法体。 
 - 这样,再用到这个接口时,可以直接继承适配器,这样就不需要把接口中的每一个方法再填充一遍了。
 - 只需要在这个类中复写一下需要用的方法。这样简单,方便。
 - 
 - @author bailu
 -  */
public class MyImpClass implements MyInterface, Serializable {
  // Serializable序列化
  private static final long serialVersionUID = 1L;
  // 重写接口的方法——适配器,
  @Override
  public void method1() {
    System.out.println(I);
  }
  @Override
  public void method2() {
  }
}
  • 抽象类之间也可以继承,但是也只是支持单继承。
  • 接口之间也可以继承,一个接口可以继承多个接口。

9.4、什么是适配器?

适配器只是一个类,它实现了接口,提供了方法体。再用到这个接口时,可以直接继承适配器,这样就不需要把接口中的每一个方法再填充一遍了,只需要在这个类中复写一下需要用的方法。

接口很好地体现了设计模式中的开闭原则。

比如,我们做一个在线商城系统,就需要调用第三方支付——银行或者是支付宝的支付接口。我们就需要第三方为我们提供接口,里面定义了抽象的方法以及实现接口的方法——适配器,我们通过调用适配器里面的方法来完成支付,代码如下:

ZsBankInter obj = 获取实现类对象;
obj.send();
京东、淘宝
银行接口ZsBankInter  
send() 
class DoSend implements ZsBankInter{
    send()具体的方法
}

总结

修饰符在 Java 语言中有四种使用情况:成员变量、成员方法、代码块和内部类。以上我们总结了在日常的开发过程中会遇到的 11 种常见的修饰符,并从最基础的底层和原理理解和疏通这些常见修饰符语法说明以及常见的开发应用案例。其中具体的内容还有很多,本文就暂不一一列举,待日后根据开发需要补充完毕。

image.png


我是白鹿,一个不懈奋斗的程序猿。望本文能对你有所裨益,欢迎大家的一键三连!若有其他问题、建议或者补充可以留言在文章下方,感谢大家的支持!


相关文章
|
1月前
|
监控 Java API
如何使用Java语言快速开发一套智慧工地系统
使用Java开发智慧工地系统,采用Spring Cloud微服务架构和前后端分离设计,结合MySQL、MongoDB数据库及RESTful API,集成人脸识别、视频监控、设备与环境监测等功能模块,运用Spark/Flink处理大数据,ECharts/AntV G2实现数据可视化,确保系统安全与性能,采用敏捷开发模式,提供详尽文档与用户培训,支持云部署与容器化管理,快速构建高效、灵活的智慧工地解决方案。
|
3天前
|
移动开发 前端开发 Java
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
JavaFX是Java的下一代图形用户界面工具包。JavaFX是一组图形和媒体API,我们可以用它们来创建和部署富客户端应用程序。 JavaFX允许开发人员快速构建丰富的跨平台应用程序,允许开发人员在单个编程接口中组合图形,动画和UI控件。本文详细介绍了JavaFx的常见用法,相信读完本教程你一定有所收获!
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
|
26天前
|
Java 开发者 微服务
Spring Boot 入门:简化 Java Web 开发的强大工具
Spring Boot 是一个开源的 Java 基础框架,用于创建独立、生产级别的基于Spring框架的应用程序。它旨在简化Spring应用的初始搭建以及开发过程。
48 6
Spring Boot 入门:简化 Java Web 开发的强大工具
|
14天前
|
存储 JavaScript 前端开发
基于 SpringBoot 和 Vue 开发校园点餐订餐外卖跑腿Java源码
一个非常实用的校园外卖系统,基于 SpringBoot 和 Vue 的开发。这一系统源于黑马的外卖案例项目 经过站长的进一步改进和优化,提供了更丰富的功能和更高的可用性。 这个项目的架构设计非常有趣。虽然它采用了SpringBoot和Vue的组合,但并不是一个完全分离的项目。 前端视图通过JS的方式引入了Vue和Element UI,既能利用Vue的快速开发优势,
79 13
|
19天前
|
算法 Java API
如何使用Java开发获得淘宝商品描述API接口?
本文详细介绍如何使用Java开发调用淘宝商品描述API接口,涵盖从注册淘宝开放平台账号、阅读平台规则、创建应用并申请接口权限,到安装开发工具、配置开发环境、获取访问令牌,以及具体的Java代码实现和注意事项。通过遵循这些步骤,开发者可以高效地获取商品详情、描述及图片等信息,为项目和业务增添价值。
52 10
|
12天前
|
前端开发 Java 测试技术
java日常开发中如何写出优雅的好维护的代码
代码可读性太差,实际是给团队后续开发中埋坑,优化在平时,没有那个团队会说我专门给你一个月来优化之前的代码,所以在日常开发中就要多注意可读性问题,不要写出几天之后自己都看不懂的代码。
50 2
|
22天前
|
JavaScript 安全 Java
java版药品不良反应智能监测系统源码,采用SpringBoot、Vue、MySQL技术开发
基于B/S架构,采用Java、SpringBoot、Vue、MySQL等技术自主研发的ADR智能监测系统,适用于三甲医院,支持二次开发。该系统能自动监测全院患者药物不良反应,通过移动端和PC端实时反馈,提升用药安全。系统涵盖规则管理、监测报告、系统管理三大模块,确保精准、高效地处理ADR事件。
|
27天前
|
Java
java do while 的语法怎么用?
java do while 的语法怎么用?
39 3
|
1月前
|
开发框架 Java 关系型数据库
Java哪个框架适合开发API接口?
在快速发展的软件开发领域,API接口连接了不同的系统和服务。Java作为成熟的编程语言,其生态系统中出现了许多API开发框架。Magic-API因其独特优势和强大功能,成为Java开发者优选的API开发框架。本文将从核心优势、实际应用价值及未来展望等方面,深入探讨Magic-API为何值得选择。
55 2
|
1月前
|
监控 前端开发 Java
【技术开发】接口管理平台要用什么技术栈?推荐:Java+Vue3+Docker+MySQL
该文档介绍了基于Java后端和Vue3前端构建的管理系统的技术栈及功能模块,涵盖管理后台的访问、登录、首页概览、API接口管理、接口权限设置、接口监控、计费管理、账号管理、应用管理、数据库配置、站点配置及管理员个人设置等内容,并提供了访问地址及操作指南。