首页 > 编程语言 >Java语言中的修饰符

Java语言中的修饰符

时间:2023-09-11 11:11:37浏览次数:63  
标签:Java 语言 修饰符 static 修饰 方法 final 变量

Java语言中的修饰符

修饰符 成员方法 构造方法 成员变量 局部变量
abstract
static
public
protected(受保护的)
private(私有的)
synchronized(同步的)
native(本地的)
transient(暂时的)
volatile(易失的)
final(不可改变)
  • 修饰顶层:abstract public final(static protected private不能)
  • 成员方法和成员变量可以有多种修饰符,局部变量只能用final修饰

7.1 访问控制修饰符

访问级别 访问控制修饰符 同类 同包 子类 不同的包
公开 Public
受保护 Protected
默认 没有访问控制修饰符
私有 Private

7.2 abstract修饰符

abstract修饰符可用来修饰类和成员方法:

  • 用abstract修饰的类表示抽象类,抽象类位于继承树的抽象层,抽象类不能被实例化,即不允许创建抽象类本身的实例。没有用abstract修饰的类称为具体类,具体类可以被实例化。
  • 用abstract修饰的方法表示抽象方法,抽象方法没有方法体。抽象方法用来描述系统具有什么功能,但不提供具体的实现。没有用abstract修饰的方法称为具体方法,具体方法具有方法体。

使用abstarct修饰符需要遵循以下语法规则:

  1. 抽象类中可以没有抽象方法,但包含了抽象方法的类必须被定义为抽象类。如果子类没有实现父类中所有的抽象方法,那么子类也必须定义为抽象类,否则编译出错。例如,以下代码中Sub类继承了Base类,但Sub类仅实现了Base类中的method1()抽象方法,而没有实现method2()抽象方法,因此Sub类必须声明为抽象类,否则编译出错:
abstract class Base{
    abstract void method1();
    abstract void method2();
}
//编译出错,Sub必须声明为抽象类
Class Sub extends Base{
    void method1(){
        System.out.println("method1")
    }
}
  1. 没有抽象静态方法
abstract class Base{
	static abstract void method10;//编译出错,static和abstract修饰符不能连用
	static void method2(){···}//合法,抽象类中可以有静态方法
}    
  1. 抽象类中可以有非抽象的构造方法,创建子类的实例时可能会调用这些构造方法,关于父类构造方法的调用规则参见本书第11章的11.2.3节(子类调用父类的构造方法)。抽象类不能被实例化,然而可以创建一个引用变量,其类型是一个抽象类,并让它引用非抽象的子类的一个实例。例如:
abstract class Base{}
class Sub extends Base{
    public static void main(String[] args) {
        Base base1 = new Base();//错误:Base是抽象的; 无法实例化
        Base base2 = new Sub();
    }
}
  1. 抽象类及抽象方法不能被final修饰符修饰。abstract修饰符与final修饰符不能连用,因为抽象类只有允许创建其子类,它的抽象方法才能被实现,并且只有它的具体子类才能被实例化,而用final修饰的类不允许拥有子类,用final修饰的方法不允许被子类方法覆盖,两此把abstract修饰符与final修饰符连用,会导致自相矛盾。
  2. 抽象方法不能被private修饰符修饰。这是因为如果方法是抽象的,表示父类只声明具备某种功能,但没有提供实现。这种方法有待于某个子类去实现它。则abstract必须可见。假如Java允许把父类的方法同时用abstract和private修饰,那就意味着在父类中声明一个永远无法实现的方法,所以在Java中不允许出现这一情况。

7.3 final修饰符

final具有“不可改变的”的含义,它可以修饰非抽象类、非抽象成员方法和变量:

  • 用final修饰的类不能被继承,没有子类。
  • 用final修饰的方法不能被子类的方法覆盖。
  • 用final修饰的变量表示常量,只能被赋一次值。

final不能用来修饰构造方法,因为“方法覆盖”这一概念仅适用于类的成员方法,而不适用于类的构造方法,父类的构造方法和子类构造方法之间不存在覆盖关系,因此private类型的方法默认为final

7.3.1 final类

在第6章的6.7.3节(继承关系的最大弱点:打破封装)曾经指出,继承关系的弱点是打破封装,子类能够

访问父类的实现细节,而且能以方法覆盖的方式修改实现细节。在以下情况,可以考虑把类定义为final类型,使得这个类不能被继承:

  • 不是专门为继承而设计的类,类本身的方法之间有复杂的调用关系。假如随意创建这些类的子类,子类有可能会错误地修改父类的实现细节。
  • 出于安全的原因,类的实现细节不允许有任何改动。
  • 在创建对象模型时,确信这个类不会再被扩展。

7.3.2 final方法

在某些情况下,出于安全的原因,父类不允许子类覆盖某个方法,此时可以把这个方法声明为final类型。

7.3.3 final 变量

用final修饰的变量表示取值不会改变的常量。final变量具有以下特征:

  1. final修饰符可以修饰静态变量实例变量局部变量,分别表示静态常量、实例常量和局部常量。例如,某个中学的学生都有出生日期、姓名和年龄这些属性,其中学生的出生日期永远不会改变,姓名有可能改变,年龄每年都会变化。此外,该中学在招收学生时,对学生的年龄做了限制,只会招收年龄在10~23岁的学生。以下
    是Student类的源程序,其中学生的最大年龄及最小年龄为静态常量,学生的出生日期为实例常量。
  2. final类型的变量都必须显式初始化
  3. final变量只能赋一次值。例如,以下程序代码试图给var1实例常量和var局部常量赋两次值,并且试图改变final类型的参数param的值,这会导致编译错误:
public class Sample{
	private final int varl=1;//定义并初始化varl实例常量
	public Sample(){
		varl=2;//编译出错,不允许改变varl实例常量的值
		public void method(final int param){
			final int var2=1;//定义并初始化var2局部常量
			var2++;//编译出错,不允许改变var2局部常量的值
			param++;//编译出错,不允许改变final类型参数的值
        }
    } 
}    
  1. 如果将引用类型的变量用final修饰,那么该变量只能始终引用一个对象,但可以改变对象的内容,例如:
public class Sample{
    public int var;
    public Sample(int var){
        this.var = var;
    }
    public static void main(String args[]) {
        final Sample s = new Sample(1);
        //合法,定义并初始化 final类型的引用变量s
        s.var = 2;
        //合法,修改引用变量s所引用的Sample对象的var属性
        s = new Sample(2);
        //编译出错,不能改变引用变量s所引用的Sample对象
    }
}

7.4 static 修饰符

static修饰符可以用来修饰类的成员变量、成员方法和代码块:

  • 用static修饰的成员变量表示静态变量,可以直接通过类名来访问。
  • 用static修饰的成员方法表示静态方法,可以直接通过类名来访问。
  • 用static修饰的程序代码块表示静态代码块,当Java虚拟机加载类时,就会执行该代码块。

7.4.1 static 变量

  • 类的成员变量有两种:一种是被static修饰的变量,叫类变量,或静态变量;一种是没有被static修饰的变量,叫实例变量

  • 在类的内部,可以在任何方法内直接访问静态变量;在其他类中,可以通过某个
    类的类名来访问它的静态变量。

  • static变量在某种程度上与其他语言(如C语言)中的全局变量相似。Java语言不支持不属于任何类的全局变量,静态变量提供了这一功能,它有两个作用:

    • 能被类的所有实例共享,可作为实例之间进行交流的共享数据。

    • 如果类的所有实例都包含一个相同的常量属性,可把这个属性定义为静态常量类型,从而节省内存空间。例如某种类型的变压器Transformer类,它所接受的最小输入电压为110V,最大输入电压为220V,输出电压为15V,这是对所有变压器Transformer对象适用的属性,可在Transformer类中按如下方式定义它们:

      static final int MAX INPUT VOLTAGE=220;
      static final int MIN_INPUT_VOLTAGE=110;
      static final int OUTPUT_VOLTAGE=15;
      

7.4.2 staic方法

成员方法分为静态方法和实例方法。用static修饰的方法叫静态方法或类方法。青态方法也和静态变量一样,不需创建类的实例,可以直接通过类名来访问.

7.4.3 static 代码块

类中可以包含静态代码块,它不存在于任何方法体中。Java虚拟机加载类时,会执行这些静态代码块。如果类中包含多个静态块,那么Java虚拟机按它们在类中出现的顺序依次执行它们,每个静态代码块只会被执行一次。例如以下Sample类中包含两个静态代码块。运行Sample类的main()方法时,Java虚拟机首先加载Sample类,在加载的过程中依次执行两个静态代码块。Java虚拟机机载Sample类后,再执行main()方法:

7.4.4 用 static 进行静态导入

从JDK5开始引入了静态导入语法(import static),其目的是为了在需要经常访问同一个类的方法或成员变量的场合,简化程序代码。

7.5 小结

  1. 访问控制修饰符
    • public的访问级别最高,其次是protected、默认和private。
    • 成员变量和成员方法可以处于4个访问级别中的一个:公开、受保护、默认或私有。
    • 顶层类可以处于公开或默认级别,顶层类不能被protected和private修饰。
    • 局部变量不能被访问控制修饰符修饰。
  2. abstract修饰符
    • 抽象类不能被实例化
    • 抽象类中可以没有抽象方法,但包含抽象方法的类必须为抽象方法
    • 如果子类没有实现父类中所有的抽象方法,则子类也必须定义为抽象类
    • 抽象类不能定义为final和static类型
    • 抽象方法不能定义为private,final,static类型
    • 没有抽象构造方法
    • 抽象方法没有方法体
  3. final修饰符
    • 用final修饰的类不能被继承。
    • 用final修饰的方法不能被子类的方法覆盖。
    • private类型的方法都默认为final方法,因而不能被子类的方法覆盖。
    • final类型的变量必须被显式初始化,并且只能被赋一次值。
  4. static修饰符
    • 静态变量在内存中只有一个备份,在类的所有实例中共享。
    • 在静态方法中不能直接访问实例方法和实例变量。
    • 静态方法中不能使用this和super关键字。
    • 静态方法不能被 abstract 修饰。
    • 静态方法和静态变量都可以通过类名直接被访问。
    • 当类被加载时,静态代码块只被执行一次。类中不同的静态代码块按它们在类中出现的顺序被依次执行。

标签:Java,语言,修饰符,static,修饰,方法,final,变量
From: https://www.cnblogs.com/amorfati/p/17692994.html

相关文章

  • easy javadoc easyjavadoc快捷键
    应用场景开发过程中,需要对类和方法添加注释,类的注释比较好实现,通过设置模板,在创建时即可自动创建预设的注释。而为方法添加注释,则就没那么容易,最主要的影响在于参数的处理上。虽然IDEA自身的LiveTemplate功能可以实现,但配置比较繁琐,特别是获取方法的参数列表,还需要写groovy脚本......
  • Java并发编程的艺术-PDF下载-firebook-书火网
    Java并发编程的艺术-PDF下载-firebook-书火网资源链接:https://pan.baidu.com/s/19vG6Dd3YBr69i6D2NHeCaQ提取码:wv4f第1章介绍Java并发编程的挑战,会向读者说明可能会遇到哪些问题,以及如何解决。第2章Java并发编程的底层实现原理,从CPU和JVM2个层面剖析。第3章详细深入介绍了Ja......
  • java异常处理的三种机制
    一、try-catch-finally语句(推荐)try{//可能出现异常的代码}catch(Exceptione){//处理异常的代码}finally{//无论是否出现异常都会执行的代码}try-catch-finally语句是Java中最基本也是最常用的异常处理方法。它包含三个部分:try、catch和fin......
  • 教你快速了解C语言中的作用域和常量
    (章节目录)前言  哈喽,各位铁汁们好啊!✨今天来给大家带来的是初识C语言里面的作用域、常量。  这几章主要带大家简单认识-一下C语言,俗话说没吃过猪肉,也见过猪跑。带大家了解下C语言。可以读懂C语言的简单程序,后期会给大家详细介绍C语言。一、变量作用域和生命周期作用域......
  • 我个人学习C语言的近期规划
    一.困难点最近我发现学习C语言已经变得越发的困难,接下来我说一下主要的困难点1.学习时很多前面用到的知识点已经遗忘,需要通过重复学习和看笔记才能勉强理解2.写代码时候逻辑经常出现混乱,会写出很多的bug3.困难点(对我来说)第一个就是从函数的递归开始代码很难进行构思,多次递归后就会......
  • C语言中几种类型所占字节数
    类型16位32位64位char111shortint222int244unsignedint244float444double888long448longlong888unsignedlong448......
  • c++程序设计语言
    把那些重要的东西适度地记录索引,但是一些不太重要的细节就在书上标记就行。[ch7]# void*指针的使用(149)/nullptr# 原始字符串;不同语言的大字符集(153)# 多维数组至少需要知道哪些边界大小值(160)#......
  • Java开发面试--nacos专区
    1、Nacos是什么?请简要介绍Nacos是什么以及它的主要功能和用途。答:简介:Nacos是一个开源的、高性能、动态服务发现、配置和服务管理平台,通常用于微服务架构中。Nacos的名称来源于"Naming"(服务发现)、"Configuration"(配置管理)和"Service"(服务管理)三个词的首字母组合。主要功能......
  • C语言宏定义中的#和##(转)
    https://www.jb51.net/article/282832.htm #和##是宏定义中常用的两个预处理运算符1.记号串化(#)2.记号黏结(##)3. 分析下列程序运行结果#和##是宏定义中常用的两个预处理运算符其中#用于记号串化,##用于记号黏结,下面分别介绍它们。1.记号串化(#)记号串化可以......
  • 2-2C语言学习
    #include<stdio.h>voiddouble_value(doublen);intmain(){ doublevalue; printf("Pleaseenterthedoublevalue:"); scanf_s("%lf",&value); while(value>0.00) { double_value(value); printf("\nPleaseentert......