热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【JavaSE基础专题一】常用关键字对比

我把常用关键字分为以下几种:1,访问限制修饰符;2,类,方法,变量修饰符;3&#x

我把常用关键字分为以下几种:1,访问限制修饰符;2,类,方法,变量修饰符;3,调用类型关键字;4工具类型的关键字

访问限制修饰符

访问级别共有四种:public(全部可见),protected(本包所有类和跨包子类可见),default(本包所有类可见),private(仅对本类可见)。
在这里插入图片描述
对于类、变量、方法,其实修饰符有不同的选择方式:

类的访问修饰符

访问限制修饰符对内部类和外部类不同的支持

  • 对于外部类来说,只有两种修饰,public和默认(default),因为外部类放在包中,只有两种可能,包可见和包不可见。外部类只能用public, abstract 和 final 修饰,因为外部类放在包中,只有两种可能,包可见和包不可见(2种访问权限)

  • 对于内部类来说,可以用所有的修饰,因为内部类放在外部类中,与成员变量的地位一致,所以有四种可能。内部类则可以用 修饰成员变量的修饰符修饰内部类,比如 private,static, protected ,public和默认的default修饰


成员变量的访问修饰符


  • public(公共访问修饰符)
  • protected(保护访问修饰符)指定该变量可以被自己的类、同包的类、子类访问。在子类中可以(通过super或者不调用来访问)。
  • default,在同一个包中的类可以访问,其他包中的类不能访问。
  • private(私有访问修饰符)指定该变量只允许自己的类的方法访问,其他任何类(包括子类)中的方法均不能访问

方法的访问修饰符


  • public(公共修饰符)
  • protected(保护访问修饰符)指定该方法可以被它的类和子类(通过super或者不调用来访问)进行访问。
  • default,在同一个包中的类可以访问,其他包中的类不能访问。
  • private(私有修饰符)指定此方法只能有自己的类访问,其他的类不能访问(包括子类)

需要注意的是protected,如果在子类的方法中new一个父类出来,再用父类变量去调用方法还是会报错
在这里插入图片描述

类,方法,变量修饰符

abstract和static,final是互斥的,static和final是可以连用的而且abstract不能用private、static、synchronized、native、final访问修饰符修饰。

变量方法静态代码块代码块
abstract抽象类被修饰为abstract抽象方法被修饰为abstact(与native互斥)
native本地方法被修饰为native(与abstract互斥)
final封闭类被修饰为final(与abstract互斥)基本类型被修饰后为常量,引用类型被修饰后地址不可变方法被修饰后不可被重写(与abstract互斥)
static只有静态内部类才能被修饰(与abstract互斥)被修饰后为静态变量被修饰后为静态方法(与abstract互斥)被修饰后为静态代码块
synchronized被修饰后为同步类(与abstract互斥)被修饰后为同步方法(与abstract互斥)被修饰后为同步静态代码块被修饰后为同步代码块

abstract修饰符(修饰类,方法)

abstract修饰的类叫做抽象类,abstract修饰的方法叫做抽象方法:

  1. 抽象类中可以没有抽象方法,但包含了抽象方法的类必须被定义为抽象类
  2. 没有抽象构造方法,没有抽象静态方法。 static 和 abstract不能连用
  3. 抽象类中可以有非抽象的构造方法,创建子类的实例时可能会调用这些构造方法。
  4. 抽象类及抽象方法不能被final和private修饰符修饰。final和abstract 不能连用,同样private和abstract不能连用(抽象方法就是被用来实现的)。
  5. 抽象类不能被实例化。因为抽象类可能含有没有方法体的抽象方法

其实很好理解,abstract修饰的类或方法生来就是要被实现或扩展以实现多态的,所以一切阻挠它的final、static、private这些关键字都不能使用,并且由于抽象的类或方法不能直接使用,所以synchronized、native也不能与它连用。

final修饰符(修饰类,变量,方法)

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

  1. 用final修饰的类不能被继承,没有子类
  2. 当⽤ final 修饰⼀个类时,表明这个类不能被继承。final 类中的所有成员⽅法都会被隐式地指定为 final ⽅法
  3. 用final修饰的方法不能被子类的方法覆盖(重写)
  4. 用final修饰的变量表示常量,只能被赋一次值,必须被显式初始化。但如果final修饰的是引用,它只关心引用的不可变,不关心引用指向的对象的变化
  5. private修饰的方法默认为是final方法,因而不能被子类的方法覆盖

虽说final的方法不能被覆盖,但以下这种情况可以写一样的:


class Car extends Vehicle
{public static void main (String[] args){new Car(). run();}private final void run(){System. out. println ("Car");}
}
class Vehicle
{private final void run(){System. out. println("Vehicle");}
}

首先final声明的方法是不能被覆盖的,但是这里并不错误,因为方法是private的,也就是子类没有继承父类的run方法,因此子类的run方法跟父类的run方法无关,并不是覆盖但这里如果是public修饰符就会报编译错误,因为编译器认为子类在试图覆写一个父类的final修饰的方法。

final修饰变量

当变量被final修饰的时候需要遵循:

  1. final修饰的成员变量为基本数据类型时,在赋值之后无法改变。当final修饰的成员变量为引用数据类型时,在赋值后其指向地址无法改变,但是对象内容还是可以改变的
  2. final修饰的成员变量在赋值时可以有三种方式:在声明时直接赋值;在构造器中赋值(静态的不可以);在初始代码块中进行赋值(静态final只能在静态块,动态final只能在构造块)。
  3. 因为Java允许将数据成员声明为final,却不赋初值,这种叫做blank final,但是blank final必须在使用之前初始化

准确的说blank final必须在初始化的时候赋一个初始值。

final,finally,finalize的区别

我们经常会碰到这样一组关键字对比final,finally,finalize,尽管他们很像,但其实是做不同的事:

  1. final用于声明属性,类,方法,分别表示属性不可变(基本类型的不可变,引用类型的引用不可变,对象可变),类不可被继承,方法不可被覆盖
  2. finally作为异常处理的一部分,只能用于tyr/catch语句中,并且附带一个语句块,表示这段语句一定要执行,经常被用在需要释放资源的情况下,例如文件的关闭,删除临时文件。
  3. finalize是Object类的一个方法,在垃圾回收器执行时会调用被回收对象的finalize方法。需要注意的是如果要回收该对象,首先该对象会调用它的finalize方法,在执行期间,如果它能逃逸,就可以逃逸,如果不能,那么在下一次垃圾回收动作发生时该对象被回收。(二次标记)

可以顺带记住这三个关键字的使用区别。

static修饰符(修饰变量,方法和类)

static修饰的变量可以先不初始化,常常修饰静态变量、静态方法和静态块

static作用于静态类

如果一个类要被声明为static的,只有一种情况,就是静态内部类。如果在外部类声明为static,程序会编译都不会过。

  1. 静态内部类跟静态方法一样,只能访问静态的成员变量和方法,不能访问非静态的方法和属性,但是成员内部类可以访问任意外部类的成员变量和方法
  2. 静态内部类可以声明普通成员变量和方法,而成员内部类不能声明static成员变量和方法
  3. 静态内部类可以单独初始化

static作用于静态变量


  1. 静态变量在内存中只有一个拷贝,在类的所有实例中共享

static作用于静态方法


  1. 在静态方法中不能直接访问实例方法和实例变量,需要new一个实例来访问。可想而知静态域在类加载的时候执行,那个时候还没有具体实例呢,除非用new触发主动初始化条件。
  2. 在静态方法中不能使用this和super关键字。其实this和super也是调用父类实例或本类实例的变量或方法,
  3. 静态方法不能被abstract修饰
  4. 静态方法和静态变量都可以通过类名直接被访问。

static作用于静态代码块


  • 当类被加载时,静态代码块只被执行一次。类中不同的静态代码块按它们在类中出现的顺序被依次执行

public static void main(String args[]) {} 程序入口方法,可以被final修饰,也可以被synchronized修饰,static有如下使用的注意事项:

是否可以在static环境中访问非static变量?

  • static变量在Java中是属于类的,它在所有的实例中的值是一样的。当类被Java虚拟机载入的时候,会对static变量进行初始化。如果你的代码尝试不用实例来访问非static的变量,编译器会报错,因为这些变量还没有被创建出来,还没有跟任何实例关联上。

static静态方法能不能引用非静态资源?

  • 不能,new的时候才会产生的东西,对于初始化后就存在的静态资源来说,根本不认识它。

static静态方法里面能不能引用静态资源?

  • 可以,因为都是类初始化的时候加载的,大家相互都认识。

非静态方法里面能不能引用静态资源?

  • 可以,非静态方法就是实例方法,那是new之后才产生的,那么属于类的内容它都认识。

native关键字(修饰方法)

native是方法修饰符。Native方法是由另外一种语言(如c/c++,FORTRAN,汇编)实现的本地方法。

  1. 因为在外部实现了方法,所以在java代码中,就不需要实现了,定义navtive方法时,并不提供实现体,因为其实现体是用非Java语言在外面实现的,有点类似于接口方法。
  2. Native可以和其他一些修饰符连用,但是abstract方法和Interface里的方法不能用native来修饰,因为native暗示这个方法是有实现体的,而abstract却显式指明了这个方法没有实现体。

也就是native就是修饰外部具体实现的方法,和没有实现的方法互斥

调用类型关键字

调用类型关键字有两个,分别为super和this

super关键字

在类的构造方法中,通过super语句调用这个类的父类的构造方法。在构造方法中,super语句必须作为构造方法的第一条语句。

  1. 在子类中访问父类的被屏蔽的方法和属性
  2. 在构造方法中,super语句必须作为构造方法的第一条语句。
  3. 只能在构造方法或实例方法内使用super关键字。 super关键字与类的特定实例相关

访问父类相关方法时需要用到,应用场景如下:

  1. 在子类构造方法中调用父类的构造方法
  2. 访问父类中被覆盖的同名变量或者方法(而不是父类的被限制访问的私有方法和属性例如private或有些时候可能是default的,例如父类子类不在一个包)

需要注意super关键字只能指代直接父类,不能指代父类的父类。

this关键字

this关键字用来指向当前实例对象,通常用于成员变量和局部变量重名的时候需要用this来区分成员变量和局部变量,当成员变量和局部变量不能区别时用优先就近的原则。

工具类型关键字

主要介绍instanceof和switch两个关键字

instanceof关键字

它的作用是判断一个引用类型的变量所指向的实例是否是一个类(接口,抽象类,父类)的实例,常见用法:result = object instanceof class返回一个boolean类型的值

package test;
class Base{}
class Child extends Base{}
class Grandchild extends Child{}
class TT {}
public class Singleton{public static void main(String[] args) {Grandchild g = new Grandchild();if (g instanceof Base) {System.out.println("TRUE");}else{System.out.println("FALSE");}if (g instanceof Child) {System.out.println("TRUE");}else{System.out.println("FALSE");}}
}

也可以判断自己父类的父类是不是满足,换言之,该方法可以向上穿透寻找父类

switch关键字

switch语句用于多分支选择,使用switch(expr)时,expr只能是一个枚举常量(内部是整型或字符类型)或一个整数表达式。

  1. 其中整数表达式可以是基本类型int(byte,short,char)其对应的包装类
  2. 如果要用long,float,double,必须强制转为int才可以
  3. String类型在jdk1.7支持(先对字符串里的String值调用hashcode()获取一个int类型的hash值,然后遍历所有case里字符串对应的hash值进行匹配,如果没匹配成功,则说明不存在,如果匹配成功,则接着调用字符串的equals操作进行匹配)equals的范围小于hashcode

在Java7之前,switch只能支持 byte、short、char、int或者其对应的封装类以及Enum类型作为条件。在Java7中,呼吁很久的String支持也终于被加上了。

public class StringForSwitch {public void test_string_switch() {String result=""; switch ("doctor") {case "doctor":result = "doctor";break;default:break;}}
}

反编译后的,还原成大致的Java的代码如下:

public class StringForSwitch {public StringForSwitch() {}public void test_string_switch() {String result = "";String var2 = "doctor";switch("doctor".hashCode()) {case -1326477025:if(var2.equals("doctor")) {result = "doctor";}default:break;}}
}

可以看出,字符串类型在switch语句中利用hashcode的值与字符串内容的比较来实现的;但是在case字句中对应的语句块中仍然需要使用String的equals方法来进一步比较字符串的内容,这是因为哈希函数在映射的时候可能存在冲突,switch关键字使用注意

  1. 在switch语句中,表达式的值不能是null,否则会在运行时抛出NullPointerException。在case子句中也不能使用null,否则会出现编译错误。
  2. case子句的值是不能重复的,对于字符串类型的也一样,但是字符串中可以包含Unicode转义字符。重复值的检查是在Java编译器对Java源代码进行相关的词法转换之后才进行的。也就是说,有些case字句的值虽然在源代码中看起来是不同的,但是经词法转换之后是一样的,就会在成编译错误。比如:“男”和“\u7537”就是一个意思。

以上就是Java中的一些常用关键字对比,希望能帮助到大家


推荐阅读
  • Android系统源码分析Zygote和SystemServer启动过程详解
    本文详细解析了Android系统源码中Zygote和SystemServer的启动过程。首先介绍了系统framework层启动的内容,帮助理解四大组件的启动和管理过程。接着介绍了AMS、PMS等系统服务的作用和调用方式。然后详细分析了Zygote的启动过程,解释了Zygote在Android启动过程中的决定作用。最后通过时序图展示了整个过程。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • Oracle seg,V$TEMPSEG_USAGE与Oracle排序的关系及使用方法
    本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ... [详细]
  • Java程序设计第4周学习总结及注释应用的开发笔记
    本文由编程笔记#小编为大家整理,主要介绍了201521123087《Java程序设计》第4周学习总结相关的知识,包括注释的应用和使用类的注释与方法的注释进行注释的方法,并在Eclipse中查看。摘要内容大约为150字,提供了一定的参考价值。 ... [详细]
  • 本文介绍了MVP架构模式及其在国庆技术博客中的应用。MVP架构模式是一种演变自MVC架构的新模式,其中View和Model之间的通信通过Presenter进行。相比MVC架构,MVP架构将交互逻辑放在Presenter内部,而View直接从Model中读取数据而不是通过Controller。本文还探讨了MVP架构在国庆技术博客中的具体应用。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • PHP反射API的功能和用途详解
    本文详细介绍了PHP反射API的功能和用途,包括动态获取信息和调用对象方法的功能,以及自动加载插件、生成文档、扩充PHP语言等用途。通过反射API,可以获取类的元数据,创建类的实例,调用方法,传递参数,动态调用类的静态方法等。PHP反射API是一种内建的OOP技术扩展,通过使用Reflection、ReflectionClass和ReflectionMethod等类,可以帮助我们分析其他类、接口、方法、属性和扩展。 ... [详细]
author-avatar
Amy爱爸爸爱妈妈
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有