Java修饰符详解:从基础到高级用法

在Java编程语言中,有许多修饰符可以使用,它们大致可以分为两大类:访问控制修饰符、其他类型的修饰符。

这些修饰符主要用于指定类、方法或变量的特性,并且通常位于声明语句的开头部分。下面通过一些示例来进一步说明这一点:

public class ExampleClass {  // 定义一个公共类private boolean flag;  // 私有布尔型变量static final double MONTHS = 12.0;  // 静态最终常量表示月份protected static final int DEFAULT_SIZE = 50;  // 受保护的静态整型常量public static void main(String[] args) {  // 主函数入口点// 函数的具体实现代码}
}

这段代码展示了不同种类的修饰符如何应用于类定义以及其内部成员(如变量和方法)上。public使得ExampleClass对所有其他类可见;private确保了flag仅限于该类内访问;而static final组合则用于创建不可改变的常数MONTHS和DEFAULT_SIZE,其中后者还添加了protected以允许子类访问。最后,main方法被标记为public static,这是启动程序的标准方式。


在Java中,访问控制修饰符用于限制对类、变量、方法和构造方法的访问。Java提供了四种不同的访问权限级别:

  • 默认访问权限(也称为包级私有),在同一包内可见,不使用任何修饰符。
  • 私有访问权限,使用private修饰符指定,在同一类内可见。
  • 公有访问权限,使用public修饰符指定,对所有类可见。
  • 受保护的访问权限,使用protected修饰符指定,对同一包内的类和所有子类可见。

默认访问修饰符

默认访问修饰符不需要使用任何关键字。使用默认访问修饰符声明的变量和方法只对同一个包内的类可见。接口中的变量默认是public static final,而接口中的方法默认是public。

示例:

String version = "1.5.1";
boolean processOrder() {return true;
}

私有访问修饰符 - private

私有访问修饰符是最严格的访问级别,被声明为private的方法、变量和构造方法只能在其所属类内部访问。类和接口不能声明为private。

示例:

public class Logger {private String format;public String getFormat() {return this.format;}public void setFormat(String format) {this.format = format;}
}

在这个例子中,Logger类中的format变量是私有的,因此其他类不能直接访问它。为了使其他类能够操作该变量,定义了两个公共方法:getFormat()(返回format的值)和setFormat(String)(设置format的值)。

公有访问修饰符 - public

被声明为public的类、方法、构造方法和接口可以被任何其他类访问。如果几个相互访问的public类分布在不同的包中,则需要导入相应public类所在的包。由于类的继承性,类所有的公有方法和变量都能被其子类继承。

示例:

public static void main(String[] arguments) {// ...
}

Java程序的main()方法必须设置为public,否则Java解释器将无法运行该类。

受保护的访问修饰符 - protected

被声明为protected的变量、方法和构造器能被同一个包中的任何其他类访问,也能被不同包中的子类访问。protected修饰符不能用于修饰类和接口,但可以用于方法和成员变量。接口的成员变量和成员方法不能声明为protected。

示例:

class AudioPlayer {protected boolean openSpeaker(Speaker sp) {// 实现细节}
}class StreamingAudioPlayer extends AudioPlayer {boolean openSpeaker(Speaker sp) {// 实现细节}
}

在这个例子中,AudioPlayer类中的openSpeaker方法被声明为protected,使得StreamingAudioPlayer子类可以重载该方法。如果将openSpeaker方法声明为private,则除了AudioPlayer之外的类将无法访问该方法。如果将其声明为public,则所有类都可以访问该方法。如果我们只想让该方法对其所在类的子类可见,则应将其声明为protected。

访问控制和继承

请注意以下关于方法继承的规则:

  • 父类中声明为public的方法在子类中也必须为public。
  • 父类中声明为protected的方法在子类中要么声明为protected,要么声明为public,不能声明为private。
  • 父类中声明为private的方法不能被继承。

非访问修饰符

除了访问控制修饰符外,Java还提供了一些非访问修饰符,以实现其他功能。

static 修饰符

static 修饰符用于创建类方法和类变量。静态变量和方法独立于类的实例,无论一个类实例化多少对象,静态变量都只有一份拷贝。静态方法不能使用类的非静态变量,只能通过参数列表获取数据并进行计算。

静态变量:

  • 使用 static 关键字声明的变量称为静态变量或类变量。
  • 静态变量在类的所有实例之间共享,无论创建多少个对象,静态变量只有一个副本。

静态方法:

  • 使用 static 关键字声明的方法称为静态方法。
  • 静态方法可以直接通过类名调用,不需要创建类的实例。
  • 静态方法不能访问类的非静态成员(即实例变量和实例方法)。

示例:

public class InstanceCounter {private static int numInstances = 0;protected static int getCount() {return numInstances;}private static void addInstance() {numInstances++;}InstanceCounter() {InstanceCounter.addInstance();}public static void main(String[] arguments) {System.out.println("Starting with " + InstanceCounter.getCount() + " instances");for (int i = 0; i < 500; ++i) {new InstanceCounter();}System.out.println("Created " + InstanceCounter.getCount() + " instances");}
}

在这个例子中,InstanceCounter 类使用了 static 修饰符来创建类变量 numInstances 和类方法 getCount() 和 addInstance()。每次创建一个新的 InstanceCounter 对象时,addInstance() 方法会被调用,从而增加 numInstances 的值。main 方法展示了如何通过类名直接访问静态变量和方法。

运行结果:

Starting with 0 instances
Created 500 instances

final 修饰符

final 修饰符在Java中用于创建不可变的变量、方法和类。它提供了多种用途,包括确保数据的一致性和防止继承或重写。

final 变量可以被显式初始化,并且只能初始化一次。一旦赋值后,final 变量的值就不能再改变。如果 final 变量引用的是一个对象,那么该引用不能指向其他对象,但对象内部的数据是可以修改的。

示例:

public class Test {final int value = 10; // final 变量,只能初始化一次// 声明常量的实例public static final int BOXWIDTH = 6;static final String TITLE = "Manager";public void changeValue() {// value = 12; // 这行代码会导致编译错误,因为 value 是 final 的}public static void main(String[] args) {Test test = new Test();System.out.println(test.value); // 输出 10// test.value = 15; // 编译错误}
}

在这个例子中,value 是一个 final 变量,只能初始化一次。尝试在 changeValue 方法中修改它的值会导致编译错误。BOXWIDTH 和 TITLE 是静态常量,通常与 static 修饰符一起使用来创建类常量。

final 方法

final 方法可以被子类继承,但不能被子类重写(覆盖)。声明 final 方法的主要目的是防止该方法的内容被修改。

示例:

public class Test {public final void changeName() {// 方法体System.out.println("Name changed");}
}class SubTest extends Test {// 以下代码会导致编译错误,因为 changeName 方法是 final 的// @Override// public void changeName() {//     System.out.println("Name changed in subclass");// }
}public class Main {public static void main(String[] args) {Test test = new Test();test.changeName(); // 输出 "Name changed"SubTest subTest = new SubTest();subTest.changeName(); // 输出 "Name changed"}
}

在这个例子中,Test 类中的 changeName 方法被声明为 final,因此 SubTest 类不能重写该方法。

final 类

final 类不能被继承,没有任何类能够继承 final 类的特性。这通常用于防止类的扩展,以确保类的行为不会被改变。

示例:

public final class Test {// 类体public void display() {System.out.println("This is a final class");}
}// 以下代码会导致编译错误,因为 Test 类是 final 的
// class SubTest extends Test {
//     // 类体
// }public class Main {public static void main(String[] args) {Test test = new Test();test.display(); // 输出 "This is a final class"}
}

在这个例子中,Test 类被声明为 final,因此不能被任何其他类继承。尝试创建一个继承自 Test 的子类会导致编译错误。

abstract 修饰符

abstract 修饰符在Java中用于创建抽象类和抽象方法。抽象类不能被实例化,其主要目的是为了将来对该类进行扩展。一个类不能同时被 abstract 和 final 修饰。如果一个类包含抽象方法,那么该类必须声明为抽象类,否则将出现编译错误。

抽象类

抽象类可以包含抽象方法和非抽象方法。抽象方法是没有具体实现的方法,其具体实现由子类提供。任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类。

示例:

abstract class Caravan {private double price;private String model;private String year;public abstract void goFast(); // 抽象方法public abstract void changeColor();
}

在这个例子中,Caravan 类是一个抽象类,包含两个抽象方法 goFast 和 changeColor。任何继承 Caravan 的子类都必须实现这两个方法。

抽象方法

抽象方法是一种没有任何实现的方法,其具体实现由子类提供。抽象方法不能被声明为 final 或 static。

示例:

public abstract class SuperClass {abstract void m(); // 抽象方法
}class SubClass extends SuperClass {@Overridevoid m() {// 具体实现System.out.println("Method m is implemented in SubClass");}
}

在这个例子中,SuperClass 是一个抽象类,包含一个抽象方法 m。SubClass 继承了 SuperClass 并实现了 m 方法。

synchronized 修饰符

synchronized 关键字用于确保方法或代码块在同一时间只能被一个线程访问。synchronized 修饰符可以应用于四个访问修饰符(public, private, protected, 默认)。

示例:

public synchronized void showDetails() {// 方法体System.out.println("Showing details...");
}

在这个例子中,showDetails 方法被声明为 synchronized,这意味着在同一时间只有一个线程可以访问该方法。

transient 修饰符

序列化的对象包含被 transient 修饰的实例变量时,Java 虚拟机 (JVM) 会跳过这些特定的变量,不将其序列化到文件中。transient 修饰符用于定义那些不需要持久化的变量。

示例:

public class MyClass implements Serializable {public transient int limit = 55;   // 不会被序列化public int b; // 会被序列化
}

在这个例子中,limit 变量被声明为 transient,因此在序列化时不会被保存到文件中。

volatile 修饰符

volatile 修饰符用于确保成员变量在每次被线程访问时都从共享内存中重新读取,并且当成员变量发生变化时,会强制线程将变化值写回共享内存。这样可以保证多个线程看到的是同一个值。

示例:

public class MyRunnable implements Runnable {private volatile boolean active;public void run() {active = true;while (active) {// 代码}}public void stop() {active = false;}
}

在这个例子中,active 变量被声明为 volatile,确保在一个线程调用 run 方法时,另一个线程调用 stop 方法可以正确地终止循环。

通过这些示例,可以看到 abstract、synchronized、transient 和 volatile 修饰符在不同上下文中的使用方式及其作用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/63228.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

onnx文件转pytorch pt模型文件

onnx文件转pytorch pt模型文件 1.onnx2torch转换及测试2.存在问题参考文献 从pytorch格式转onnx格式&#xff0c;官方有成熟的API&#xff1b;那么假如只有onnx格式的模型文件&#xff0c;该怎样转回pytorch格式&#xff1f; https://github.com/ENOT-AutoDL/onnx2torch提供了…

Git merge 和 rebase的区别(附图)

在 Git 中&#xff0c;merge 和 rebase 是两种用于整合分支变化的方法。虽然它们都可以将一个分支的更改引入到另一个分支中&#xff0c;但它们的工作方式和结果是不同的。以下是对这两者的详细解释&#xff1a; Git Merge 功能&#xff1a;合并分支&#xff0c;将两个分支的…

【Web】0基础学Web—js运算符、选择结构、循环结构

0基础学Web—js运算符、选择结构、循环结构 js运算符选择结构循环结构 js运算符 算术运算符: - * / %取余 赋值运算符: - * / % 单目运算符: i i --i i– 单独使用是自增1 或 自减1 如果被使用&#xff0c;先看到啥先操作啥 比较运算符&#xff1a; > 、 >、 < 、…

系列3:基于Centos-8.6 Kubernetes使用nfs挂载pod的应用日志文件

每日禅语 古代&#xff0c;一位官员被革职遣返&#xff0c;心中苦闷无处排解&#xff0c;便来到一位禅师的法堂。禅师静静地听完了此人的倾诉&#xff0c;将他带入自己的禅房之中。禅师指着桌上的一瓶水&#xff0c;微笑着对官员说&#xff1a;​“你看这瓶水&#xff0c;它已经…

tkdiff安装:Linux下文本对比工具

tkdiff在Linux下源码安装 1.下载解压2.编译安装3.配置环境变量4.验证及运行 本文&#xff0c;在Linux下使用源码安装tkdiff工具&#xff0c;以tkdiff-4.2版本为例&#xff0c;其他版本根据需要替换即可。 1.下载解压 去 http://sourceforge.net/projects/tkdiff/files/tkdiff…

耐蚀镍基合金的焊接技术与质量控制

耐蚀镍基合金是一类在腐蚀环境中具有优异性能的合金材料&#xff0c;广泛应用于化工、海洋工程、石油天然气等领域。其焊接技术与质量控制对于确保合金的使用性能和安全性至关重要。以下是对耐蚀镍基合金焊接技术与质量控制的详细探讨。 一、焊接技术 焊条选择 耐蚀镍基合金的焊…

Django REST framework(DRF)在处理不同请求方法时的完整流程

文章目录 一、POST 请求创建对象的流程二、GET 请求获取对象列表的流程三、GET 请求获取单个对象的流程四、PUT/PATCH 请求更新对象的流程五、自定义方法的流程自定义 GET 方法自定义 POST 方法 一、POST 请求创建对象的流程 请求到达视图层 方法调用&#xff1a; dispatch说明…

机器视觉与OpenCV--01篇

计算机眼中的图像 像素 像素是图像的基本单位&#xff0c;每个像素存储着图像的颜色、亮度或者其他特征&#xff0c;一张图片就是由若干个像素组成的。 RGB 在计算机中&#xff0c;RGB三种颜色被称为RGB三通道&#xff0c;且每个通道的取值都是0到255之间。 计算机中图像的…

qemu源码解析【03】qom实例

目录 qemu源码解析【03】qom实例arm_sbcon_i2c实例 qemu源码解析【03】qom实例 arm_sbcon_i2c实例 以hw/i2c/arm_sbcon_i2c.c代码为例&#xff0c;这个实例很简单&#xff0c;只用100行左右的代码&#xff0c;调用qemu系统接口实现了一个i2c硬件模拟先看include/hw/i2c/arm_s…

小程序自定义tab-bar,踩坑记录

从官方下载代码 https://developers.weixin.qq.com/miniprogram/dev/framework/ability/custom-tabbar.html 1、把custom-tab-bar 文件放置 pages同级 修改下 custom-tab-bar 下的 JS文件 Component({data: {selected: 0,color: "#7A7E83",selectedColor: "#3…

操作系统(14)请求分页

前言 操作系统中的请求分页&#xff0c;也称为页式虚拟存储管理&#xff0c;是建立在基本分页基础上&#xff0c;为了支持虚拟存储器功能而增加了请求调页功能和页面置换功能的一种内存管理技术。 一、基本概念 分页&#xff1a;将进程的逻辑地址空间分成若干个大小相等的页&am…

git企业开发的相关理论(一)

目录 一.初识git 二.git的安装 三.初始化/创建本地仓库 四.配置用户设置/配置本地仓库 五.认识工作区、暂存区、版本库 六.添加文件__场景一 七.查看 .git 文件/添加到本地仓库后.git中发生的变化 1.执行git add后的变化 index文件&#xff08;暂存区&#xff09; log…

wxpython图形用户界面编程

wxpython图形用户界面编程 一、wxpython的基础 1.1 wxpython的基础 作为图形用户界面开发工具包 wxPython&#xff0c;主要提供了如下 GUI 内容&#xff1a; 窗口。控件。事件处理。布局管理。 1.2 wxpython的类层次机构 1.3 wxpython的安装 Windows 和 macOS 平台安装&a…

水仙花数(流程图,NS流程图)

题目&#xff1a;打印出所有的100-999之间的"水仙花数"&#xff0c;并画出流程图和NS流程图。所谓"水仙花数"是指一个三位数&#xff0c;其各位数字立方和等于该数本身。例如&#xff1a;153是一个"水仙花数"&#xff0c;因为1531的三次方&#…

不配置python环境,直接用PyCharm就可以?

有的伙伴可能遇到不安装python环境只安装pycharm也可以进行运行代码。 所以自认为是不需要解释器就可以运行&#xff1f; 这个是不现实的&#xff0c;有很多伙伴可能是安装了Pycharm&#xff0c;但Pycharm看你电脑上没有解释器&#xff0c;所以在安装的时候给你默认安装在C盘…

网络安全渗透测试概论

渗透测试&#xff0c;也称为渗透攻击测试是一种通过模拟恶意攻击者的手段来评估计算机系统、网络或应用程序安全性的方法。 目的 旨在主动发现系统中可能存在的安全漏洞、脆弱点以及潜在风险&#xff0c;以便在被真正的恶意攻击者利用之前&#xff0c;及时进行修复和加固&…

爬虫数据能用于商业吗?

在当今数字化时代&#xff0c;数据已成为企业获取竞争优势的关键资源。网络爬虫作为一种数据收集工具&#xff0c;能够从互联网上抓取大量数据&#xff0c;这些数据在商业分析中扮演着重要角色。然而&#xff0c;使用爬虫技术获取的数据是否合法、能否用于商业分析&#xff0c;…

前端面试汇总(不定时更新)

目录 HTML & CSS1. XML、HTML、XHTML 有什么区别&#xff1f;⭐2. XML和JSON的区别&#xff1f;3. 是否了解W3C的规范&#xff1f;⭐4. 什么是语义化标签&#xff1f;⭐⭐5. 行内元素和块级元素的区别&#xff1f;⭐6. 行内元素和块级元素的转换&#xff1f;⭐7. 常用的块级…

SpringCloud微服务实战系列:03spring-cloud-gateway业务网关灰度发布

目录 spring-cloud-gateway 和zuul spring webflux 和 spring mvc spring-cloud-gateway 的两种模式 spring-cloud-gateway server 模式下配置说明 grayLb://system-server 灰度发布代码实现 spring-cloud-gateway 和zuul zuul 是spring全家桶的第一代网关组件&#x…

QT3学习之进阶理解信号和槽:如何自定义一个类信号,供其它类调用槽函数

下面是QWidget源码&#xff0c;定义了两个事件 /*!This event handler can be reimplemented in a subclass to receivewidget enter events.An event is sent to the widget when the mouse cursor enters thewidget.\sa leaveEvent(), mouseMoveEvent(), event() */void QWi…