第7天
# 第7天
今天说说什么是修饰符
# 修饰符
修饰符用于定义类、方法、变量等元素的访问权限和特性。
Java 中的修饰符主要有以下几种:
- 访问修饰符:用于控制类、方法、变量等元素的访问权限。Java 中有四种访问修饰符:public、protected、默认(无修饰符)和 private。
- 非访问修饰符:用于定义类、方法、变量等元素的特性。Java 中有几种非访问修饰符,如 static、final、abstract、synchronized、volatile 等。
- 注解修饰符:用于为类、方法、变量等元素添加元数据。Java 中有几种注解修饰符,如 @Override、@Deprecated、@SuppressWarnings 等。
- 泛型修饰符:用于定义泛型类、泛型方法、泛型接口等元素。Java 中有几种泛型修饰符,如
、 等。 - 枚举修饰符:用于定义枚举类。Java 中有几种枚举修饰符,如 enum 等。
- 异常修饰符:用于定义异常类。Java 中有几种异常修饰符,如 throws、throw 等。
- 同步修饰符:用于定义同步方法或同步代码块。Java 中有几种同步修饰符,如 synchronized 等。
- 其他修饰符:如 native、strictfp、transient 等。
但Java语言提供了很多修饰符,主要分为以下两类:(先记录两个)
- 访问修饰符
- 非访问修饰符
例子来说明:
public class MyClass {
private int myPrivateVariable;
public void myPublicMethod() {
// ...
}
}
# 访问修饰符
访问修饰符用于控制类、方法、变量等元素的访问权限。Java 中有四种访问修饰符:public、protected、默认(无修饰符)和 private。
- public:表示公共的,任何其他类都可以访问。例如,public class MyClass 表示 MyClass 类是公共的,任何其他类都可以访问它。示例访问
public class MyClass {
public int myPublicVariable;
public void myPublicMethod() {
// ...
}
}
- protected:表示受保护的,只有同一个包中的类和子类可以访问。例如,protected int myProtectedVariable 表示 myProtectedVariable 变量是受保护的,只有同一个包中的类和子类可以访问它。示例访问
public class MyClass {
protected int myProtectedVariable;
protected void myProtectedMethod() {
// ...
}
}
- 默认(无修饰符):表示默认的,只有同一个包中的类可以访问。例如,int myDefaultVariable 表示 myDefaultVariable 变量是默认的,只有同一个包中的类可以访问它。
- private:表示私有的,只有同一个类中的方法可以访问。例如,private void myPrivateMethod() 表示 myPrivateMethod 方法是私有的,只有同一个类中的方法可以访问它。
# 访问控制修饰符
Java 支持 4 种不同的访问权限。
default: 在同一包内可见(文件夹),不使用任何修饰符。使用对象:类、接口、变量、方法。
private:在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
public : 对所有类可见。使用对象:类、接口、变量、方法
protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
# 默认访问修饰符-不使用任何关键字
示例:
class AccessDefault {
void display() {
System.out.println("默认访问修饰符");
}
}
public class MyClass {
public static void main(String[] args) {
AccessDefault obj = new AccessDefault();
obj.display();
}
}
输出结果:
默认访问修饰符
# 私有访问修饰符-private
私有访问修饰符是最严格的访问级别,所以被声明为 private 的变量、方法和构造器只能被所属类访问,并且类和接口不能声明为 private。
示例:
public class AccessPrivate {
private String name = "哪吒";
private void display() {
System.out.println("私有访问修饰符");
}
}
public class MyClass {
public static void main(String[] args) {
AccessPrivate obj = new AccessPrivate();
//obj.display(); //编译错误
//System.out.println(obj.name); //编译错误
}
}
# 公共访问修饰符-public
被声明为 public 的类、方法、构造器和接口都能被任何其他类访问。
示例:
public class AccessPublic {
public String name = "哪吒";
public void display() {
System.out.println("公共访问修饰符");
}
}
# protected
protected 对同一个包内的类和所有子类可见。
示例:
public class AccessProtected {
protected String name = "哪吒";
protected void display() {
System.out.println("受保护的访问修饰符");
}
}
public class MyClass {
public static void main(String[] args) {
AccessProtected obj = new AccessProtected();
//obj.display(); //编译错误
//System.out.println(obj.name); //编译错误
}
}
# 访问控制和继承
- 当子类继承父类时,子类可以继承父类的 public 和 protected 成员,但不能继承父类的 private 成员。如果子类和父类不在同一个包中,子类只能继承父类的 public 成员。
- 父类中声明为 public 的方法在子类中也必须为 public。
- 父类中声明为 protected 的方法在子类中要么声明为 protected,要么声明为 public,不能声明为 private。
- 父类中声明为 private 的方法,不能够被子类继承。
# 非访问修饰符
非访问修饰符用于定义类、方法、变量等元素的特性。Java 中有几种非访问修饰符,如 static、final、abstract、synchronized、volatile 等。
- static: 表示静态的,用于定义静态变量、静态方法和静态代码块。静态变量和方法属于类,而不是某个具体的对象。静态变量在类加载时初始化,并且只有一个副本。静态方法不能访问非静态变量和方法,只能访问静态变量和方法。
- final: 表示最终的,用于定义常量、方法和类。常量一旦被初始化,就不能再被修改。方法被声明为 final,就不能被重写。类被声明为 final,就不能被继承。
- abstract: 表示抽象的,用于定义抽象类和抽象方法。抽象类不能被实例化,只能被继承。抽象方法没有方法体,必须在子类中实现。
- synchronized: 表示同步的,用于定义同步方法或同步代码块。同步方法或代码块在同一时间只能被一个线程访问,以保证线程安全。
- volatile: 表示易变的,用于定义易变变量。易变变量可以被多个线程同时访问和修改,并且每次访问时都会从主内存中读取最新的值,而不是从线程的本地缓存中读取。
- transient: 表示瞬态的,用于定义瞬态变量。瞬态变量在序列化时不会被保存,即不会被写入到序列化文件中。
- native: 表示本地的,用于定义本地方法。本地方法是用其他语言(如 C 或 C++)编写的,并且不能在 Java 中实现。
- strictfp: 表示严格浮点,用于定义严格浮点计算的方法或类。严格浮点计算遵循 IEEE 754 标准,以保证计算结果的一致性。
简单易懂:
- static 修饰符,用来修饰类方法和类变量。
- final 修饰符,用来修饰类、方法和变量,final 修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。
- abstract 修饰符,用来创建抽象类和抽象方法。
- synchronized 和 volatile 修饰符,主要用于线程的编程。
# 静态变量:
static 关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有一份拷贝。 静态变量也被称为类变量。局部变量不能被声明为 static 变量。
# 静态方法:
static 关键字用来声明独立于对象的静态方法。静态方法不能使用类的非静态变量。静态方法从参数列表得到数据,然后计算这些数据。
# static 修饰符用来创建类方法和类变量
示例:
public class MyClass {
static int myStaticVariable = 10;
static void myStaticMethod() {
System.out.println("静态方法");
}
public static void main(String[] args) {
MyClass.myStaticMethod();
System.out.println(MyClass.myStaticVariable);
}
}
输出结果:
静态方法
10
# final 修饰符
示例:
public class MyClass {
final int myFinalVariable = 10;
final void myFinalMethod() {
System.out.println("final 方法");
}
public static void main(String[] args) {
MyClass obj = new MyClass();
//obj.myFinalVariable = 20; //编译错误
//obj.myFinalMethod(); //编译错误
}
}
输出结果:
final 方法
# abstract 修饰符
示例:
public abstract class MyClass {
abstract void myAbstractMethod();
}
输出结果:
abstract 方法
abstract class Caravan{
private double price;
private String model;
private String year;
public abstract void goFast(); //抽象方法
public abstract void changeColor();
}
public abstract class SuperClass{
abstract void m(); //抽象方法
}
class SubClass extends SuperClass{
//实现抽象方法
void m(){
.........
}
}
# synchronized 修饰符
synchronized 关键字声明的方法同一时间只能被一个线程访问。synchronized 修饰符可以应用于四个访问修饰符。
示例:
public class MyClass {
synchronized void mySynchronizedMethod() {
System.out.println("同步方法");
}
public static void main(String[] args) {
MyClass obj = new MyClass();
obj.mySynchronizedMethod();
}
}
输出结果:
同步方法
# volatile 修饰符
volatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
一个 volatile 对象引用可能是 null。
示例:
public class MyClass {
volatile boolean myVolatileVariable = true;
public static void main(String[] args) {
MyClass obj = new MyClass();
//obj.myVolatileVariable = false; //编译错误
}
}
输出结果:
volatile 变