Java几个重要的关键字详析

目录
  • 1.extends
  • 2.implements
  • 3.final
  • 4.native
  • 5.static
  • 6.transient
  • 7.synchronized
  • 9.this
  • 10.super
    • 10.1.子类对象实例化的过程
  • 11.访问修饰符

1.extends

  • 用于类继承类,用法:class+子类名+extends+父类名+{}
class Animal{}//父类
class cat extends Animal{}//子类用extends实现继承 

注意:一个类只能用extends关键字声明继承一个父类

  • 用于接口继承接口,用法:interface+接口名+extends+接口名+{}
interface Clippers {}
interface Warriors {}
interface Lakers extends Clippers,Warriors {}//接口类用extends关键字继承其他接口(可多个)

注意:

  • 接口不能用extends声明继承别的
  • 接口只能用extends声明继承别的接口,且可以继承多个接口
  • 当一个类用implements实现了一个接口时,不仅要实现该接口的方法,也要实现该接口继承的接口的方法

2.implements

  • 用于声明一个类实现了一个接口类,用法:class+类名+implements+接口名+{}
class Nets implements Clippers,Warriors{}//用implements关键字声明实现了两个接口类

注意:

  • 一个普通类可以implements关键字声明实现多个接口,但必须实现所有接口中的所有方法
  • 抽象类实现接口,可以不用实现接口的方法(因为抽象类中可以有抽象方法)
  • 意义:可以用implements关键字声明实现多个接口来实现类似多继承

3.final

使用方法:

  • 修饰,使该类不能被继承
  • 修饰方法,使该方法不能被子类重写 (仍可以被继承调用
  • 修饰属性,使该属性的值不能被修改(使为常量
  • 修饰局部变量,使该变量不能被修改(局部常量

使用细节:

final修饰的属性在定义时必须赋初值,且不能修改,可以在以下位置赋初值

  • 定义时(显示初始化)
  • 在构造器中
  • 在代码块中

static final:全局常量

  • 如果final修饰的属性是静态(static)的,则不能在构造器中赋初值,原因:静态属性要求在类加载时就有初值,而构造器在创建对象时才被调用,所以可能导致调用静态属性时没有创建对象而没有给静态属性赋值
  • final不能修饰构造方法,没有意义
  • finalstatic同时修饰的属性在调用时不会导致类的加载,效率更高

4.native

基本介绍:

native用来修饰方法,被修饰的方法即成为了一个Java调用但非Java代码实现的接口(本地方法) ,该方法在外部可以用任何语言去实现

"A native method is a java method whose implementation is provided by non-java code."

使用方法:

native修饰方法的位置必须在方法返回类型之前,和方法访问修饰符位置没有要求,如:public native int hashCode();

native细节:

  • native方法没有方法体,也没有{}
  • native修饰后的方法不能用abstract修饰,因为abstract指明该方法无实现体,而native方法是有实现体的,只是用非Java代码实现的
  • native方法的返回类型可以是任意类型
  • 如果一个有native方法的类被继承子类会继承这个native方法,并且可以用java语言重写

使用JNI(Java Native Interface) 与其他语言交互

JNIJava平台的一部分,它允许Java代码和其他语言写的代码进行交互。

使用步骤:

  • 编写带有native方法的java类,生成.java文件
  • 使用javac命令编译生成.class文件
  • 使用javah -jni 类名 生成.h文件
  • 使用C/C++(或者其他编程语言)实现native方法,创建.cpp(或其他)文件
  • C/C++编写的文件创建动态链接库(生成DLL文件)
  • native方法中使用System.loadLibrary()方法加载动态库,将DLL文件名作为参数传入,这时候再运行.java程序即可实现对本地方法的调用

详细步骤参考

native意义:

Java无法直接访问到操作系统底层(如系统硬件),但通过使用native关键字修饰方法可以借用其他的语言来扩展Java程序的功能,提高程序的效率

5.static

修饰变量,成为静态变量或者类变量

  • 使用方法:访问修饰符+``static``+数据类型+变量名

注意事项:

  • 静态变量会被类的所有对象实例共享,并且在类加载的时候就会初始化。
  • 静态变量的访问方法(遵守相关访问权限):类名.静态变量名 或者 对象名.静态变量名

修饰方法,成为静态方法或者类方法

  • 使用方法:访问修饰符+``static``+返回数据类型+方法名+{}

注意事项:

  • 调用方法(遵守相关访问权限):类名.静态方法名 或者 对象名.静态方法名
  • 静态方法普通方法都是随着类加载而加载,将结构信息存储在方法区
  • 静态方法中不允许使用thissuper关键字
  • 静态方法中只能访问静态变量静态方法
  • 普通方法可以访问静态成员和普通成员
  • 修饰代码块,成为静态代码块

静态代码块会在类加载时被加载,优先级和静态属性一样,有多个静态代码块和静态属性时,初始化顺序按定义顺序执行

好处:static关键字的使用,将类中的一些成员修饰成静态的,这样我们不需要创建该类的对象就可以调用该成员,大大提高了编程效率

6.transient

基本介绍:

transient用于修饰实现了Serilizable接口的类中的成员变量,在该类的实例对象进行序列化处理时transient修饰的成员变量不会进行序列化

使用例子:

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectOutputStream;
import java.io.Serializable;
public class outStream {
    public static void main(String[] args) throws IOException {
        String filePath = "d:\Cat.txt";
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
        oos.writeObject(new Cat("小花猫", 3));
        oos.close();
    }
}
class Cat implements Serializable {
    private String name;
    private int age; //没有用transient修饰
    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "Car{" +

                "name='" + name + ''' +

                ", age=" + age +

                '}';
    }
}
public class inStream {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        String filePath = "d:\Cat.txt";
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
        System.out.println(ois.readObject());
        ois.close();
    }
}

可以在Cat.txt文件内看到两个成员变量都能被序列化,并且能被反序列化读出信息。

当小花猫觉得自己的年龄是隐私不想被读出时,transient修饰成员变量age:

......
private String name;
private transient int age; //使用transient修饰
......

这时在Cat.txt文件中可以看到只有name一个成员变量被序列化,反序列化后的成员变量age读出的是int类型的默认值,说明对于transient修饰的成员变量,在类的实例对象序列化的过程中会被忽略

transient细节

  • transient修饰的成员变量可以理解为:不会参与进行对象的序列化和反序列化过程,生存周期仅存于调用者的内存不会写进磁盘里进行持久化
  • static修饰的成员变量(静态变量)也是不可序列化的,不论被transient修饰与否

因为序列化是保存的实例对象的状态,而静态变量保存的是类的状态

  • transient关键字只能修饰变量,不能修饰方法和类
  • transient关键字不能修饰局部变量
  • transient关键字修饰的是自定义类的变量,则该类需要实现Serilizable接口

注意:

实现Serilizable接口的类的实例对象是自动进行序列化的,如果序列化对象的类实现的是Externalizable接口,则序列化不会自动进行,需要实现接口内的方法指定要序列化的变量,这时与有无Transient修饰无关

7.synchronized

基本介绍:

关键字synchronized可以保证在同一时刻只有一个线程可以执行被synchronized修饰的方法或代码块

线程同步

程序中多个线程都要使用同一个方法,而这个方法用synchronized进行了修饰,在多个线程调用这个方法时必须遵循同步机制

线程同步机制

当一个线程使用synchronized修饰的方法时,其他线程想使用这个方法时就必须等待,直到这个线程使用完synchronized方法

synchronized使用方法:

  • 普通同步方法:public synchronized void m () {}
public class syn implements Runnable {
    static int i = 0;
    public static void main(String[] args) throws InterruptedException {
        syn test = new syn();
        Thread t1 = new Thread(test);
        Thread t2 = new Thread(test);
        t1.start();
        t2.start();
    }
    public synchronized void increase() {//被synchronized修饰的同步方法
        System.out.println(Thread.currentThread().getName() + "调用:" + i++);

    }
    @Override
    public void run() {
        for (int j = 0; j < 100; j++) {
            increase();
        }
    }
}

两个线程同时调用一个对象的一个同步方法,由于一个对象只有一把锁,所以只有一个线程能够获得该对象的锁,另一个线程无法获得,就不能调用该对象的synchronized方法,需要等对象被释放后才能调用

从运行结果中可以证明线程1抢到了锁,线程0必须等待线程1执行完毕,否则不能访问该同步方法。

  • 静态同步方法:public static synchronized void m () {}
public class syn implements Runnable {
    static int i = 0;
    public static void main(String[] args) throws InterruptedException {
        syn test = new syn();
        syn test1 = new syn();
        Thread t1 = new Thread(test);//传入实例对象test
        Thread t2 = new Thread(test1);//传入实例对象test1
        t1.start();
        t2.start();
    }
    public static synchronized void increase() {//同步静态方法
        System.out.println(Thread.currentThread().getName() + "调用:" + i++);
    }
    @Override
    public void run() {
        for (int j = 0; j < 100; j++) {
            increase();
        }
    }
}

虽然两个线程实例化了两个不同的对象,但是synchronized修饰的是静态方法,两个线程仍然发生了互斥,因为静态方法是依附与类的而不是对象,线程1先抢到了类的锁,而线程0必须等待线程1执行完毕释放才能调用同步方法

  • 同步代码块:synchronized(object) {}
public class syn implements Runnable {
    static Object object = new Object();//共享对象
    public static void main(String[] args) throws InterruptedException {
        syn test = new syn();
        syn test1 = new syn();
        Thread t1 = new Thread(test);
        Thread t2 = new Thread(test1);
        t1.start();
        t2.start();

    }
    @Override
    public void run() {
        synchronized (object) {//代码块用静态成员变量上锁
            for (int j = 0; j < 100; j++) {
                System.out.println(Thread.currentThread().getName() + "调用第" + j + "次");
            }
        }
    }
}

同步代码块用两个实例变量共享的静态成员object对象来上锁,虽然是两个线程实例化两个不同的对象,但是对整个syn类来说只有一个共享的object对象,所以只有一把锁,每当有线程来访问代码块时需持有锁,对象锁被其他线程持有时需等待。线程1需要等线程0执行完毕才能访问同步代码块

同步的局限性:

由于同步的方法或代码块只能同一时间让一个线程访问,所以会导致程序的执行效率降低

尽可能synchronized修饰的范围最小化,来减少互斥对程序执行带来的影响

8.volatile

基本介绍:

volatile用于修饰变量,用volatile修饰的变量的值被某个线程修改时,会强制将修改的值立即写入主存中,主存中的值更新会使得缓存中的该变量的值失效,对比与非volatile变量,可能会被其他线程读取到更新前的值。

使用方法:

//现在有线程1和线程2同时执行下列代码
int i = 0;
i = i + 1;

执行完毕后预想的结果是 i = 2;但是可能存在这样一种情况:两个线程先同时把i的值读取到自己的工作内存中,然后再分别执行 i = i + 1 的操作,再将结果写入主存,这样两个线程写入的都是 i = 1,最终 i 的结果是 1 ,而不是 2

但如果 i 是 volatile 修饰的变量就会不一样了,在一个线程修改 i的值后,会立即强制在主存中更新 i 的值,这样会导致另一个线程的工作内存中 i 的缓存值无效,所以另一个线程再次从主存中读取新的 i 的值,这样保证了i的值是最新并正确的

并发编程的三大概念:

  • 原子性:执行一个操作时,要么全部步骤执行完毕且不被中断,要么就不执行
x = 100;//是原子性操作
y = x;//不是原子性操作,可分解为:1.先读取x的值    2.将x的值写入主存
x ++;//不是原子性操作,可分解为:1.读取x的值    2.进行加一操作    3.写入主存
  • 可见性:多个线程对同一个变量进行操作时,一个线程修改了变量的值,其他线程能立即看到修改的值
  • 有序性:程序执行的顺序按照代码的先后顺序执行

volatile的意义

  • 保证了不同线程对变量进行修改时的可见性:因为对于volatile变量来说,被修改后新值对其他线程来说是立即可见的
  • 保证了有序性volatile禁止了指令重排,它能保证在对volatile修饰的变量进行操作时,之前的代码语句已经全部被执行,并且后面的语句都未执行,但是对其他语句的顺序是不做保证的

注意: volatile不能保证原子性,因为不能保证对变量的操作是原子性操作

9.this

  • 在方法中修饰属性,this理解为当前对象,用来区别成员方法和形参,通常省略
  • 修饰方法,this理解为当前对象,通常省略;不能在静态方法中使用
  • 调用构造器,在构造器中使用this(形参列表)显式调用指定的其他构造器
    • 必须在首行调用其他构造器
    • 一个构造器中不能调用多个其他构造器
    • 不能在构造器中调用递归调用,不能成环调用

10.super

super可以理解为:父类的

  • 修饰属性:去父类中找对应属性,用来区分子父类重名的属性
  • 修饰方法:调用重写之前的方法
  • 调用构造器:使用super(形参列表)指定调用父类构造器
    • super(形参列表)必须放在构造器的首行
    • super(形参列表)this(形参列表)只能二选一
    • 在构造器首行如果没有显式声明super(形参列表)this(形参列表)则默认调用父类的空参构造器super()(如果此时父类中没有空参构造器就会报错)
  • 不能在静态方法中使用

当一个方法和属性被static属性修饰时,这些方法和属性是优先于对象加载进入内存的,是随着类的加载而加载的;this是当前对象的引用,super是指父类的引用,当静态方法加载进内存进栈时,如果在静态方法中有this和super关键字时,this和super也被加载到了内存,但是这个时候并没有对象的引用,this和super没有初始化,所有编译会报错。

10.1.子类对象实例化的过程

11.访问修饰符

public修饰类:

  • 一个类中最多只能有一个public类,且文件名要和public类一致
  • 如果没有public类,文件名可以任意

到此这篇关于Java几个重要的关键字详析的文章就介绍到这了,更多相关Java关键字内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java深入讲解instanceof关键字的使用

    目录 instanceof关键字的使用 1. 语法格式 2. 类型转换 (Casting) 2.1 基本数据类型的Casting 2.2 对象类型转换 2.3 代码演示 3. 错误举例 instanceof关键字的使用 1. 语法格式 x instanceof A:检验x是否为类A的对象,返回值为boolean类型,如果是,返回true:如果不是,返回false. 要求x所属的类与类A必须是子类和父类的关系,否则编译错误 如果x属于类A的子类B,x instanceof A值也为true pub

  • Java基础学习之关键字和变量数据类型的那些事

    目录 一. 关键字 二. 变量 2.1 变量的定义 2.2 变量的分类 1. 按照数据类型分类 三. 字符编码 补充:变量的声明和初始化 总结 一. 关键字 Java中的关键字是由特定的单词组成,单词全为小写字母,每个都有特殊的含义,其实Java关键字也就那几十个,这个不需要背,以后都会知晓: 将以上关键字分类大概是这样的: tips: 值得注意的是goto,以前的时候还在用,现在作为Java的保留字,已经不用了,但是还是存在的,保留下来而已. Java中需要我们自定义的名字叫做标识符.比如方法

  • Java中的static关键字修饰属性和方法(推荐)

    目录 static关键字 1.static修饰属性(静态属性) 1.1.哪些成员属性可以被static修饰. 1.2.静态属性的访问. 2.static关键字修饰方法 1.那些方法可以使用static修饰 2.常见的问题 static关键字 static关键词与对象无关.static关键字主要修饰四个部分的内容 这里我们主要介绍static修饰属性和修饰方法. 1.static修饰属性(静态属性) 1.1.哪些成员属性可以被static修饰. 我们把static修饰的属性称为静态属性,又叫类属性

  • Java超详细分析讲解final关键字的用法

    目录 基本介绍 final细节01 final细节02 基本介绍 final 可以修饰类.属性.方法和局部变量. 在某些情况下,程序员可能有以下需求,就会使用到final: Base Sub 类 1)当不希望类被继承时,可以用final修饰. 2)当不希望父类的某个方法被子类覆盖/重写(override)时,可以用final关键字 修饰.[案例演示:访问修饰符 final 返回类型方法名] 3)当不希望类的的某个属性的值被修改,可以用final修饰.[案例演示: public final dou

  • Java深入探究关键字abstract的使用

    目录 1. 理解 2. 作用 3. 修饰类-抽象类 4. 修饰方法-抽象方法 5. 代码演示 6. 经典题目 7. 抽象类的匿名子类 8. 应用-模板方法设计模式(TemplateMethod) 1. 理解 abstract:抽象的 2. 作用 abstract可以用来修饰类.方法. 不能用abstract修饰变量.代码块.构造器. 不能用abstract修饰私有方法.静态方法.final的方法.final的类. 3. 修饰类-抽象类 抽象类中一定有构造器,便于子类实例化时调用(涉及:子类对象实

  • java中构造方法及this关键字的用法实例详解(超详细)

    目录 初识构造方法 构造方法的使用 初识this this.xx的用法 this()用于构造函数的调用 总结 初识构造方法 我们上篇讲了java中类的创建,那么让我们来实战演练一下:创建一个学生类,里面有学生的基本信息,包括姓名.性别.年龄.学号,你可能会写出这样的代码: class Student { String name; String gender; int age; long studentID; } public class TestDemo2 { public static voi

  • Java实现统计文档中关键字出现的次数

    目录 1.实现URL文档的拷贝 2.实现关键词在文档的查询功能 3.显示效果 该代码简易实现了获取URL地址后对文档进行关键字统计的功能.具体的自己看吧 1.实现URL文档的拷贝 import java.util.Scanner; import java.util.regex.Pattern; import java.net.*; import java.io.*; import javax.swing.*; import javax.swing.UIManager; import java.a

  • Java几个重要的关键字详析

    目录 1.extends 2.implements 3.final 4.native 5.static 6.transient 7.synchronized 9.this 10.super 10.1.子类对象实例化的过程 11.访问修饰符 1.extends 用于类继承类,用法:class+子类名+extends+父类名+{} class Animal{}//父类 class cat extends Animal{}//子类用extends实现继承 注意:一个类只能用extends关键字声明继承

  • Java中super和this关键字详解

    目录 父类空间优先于子类对象产生 super和this的含义 super和this的用法 继承的特点 父类空间优先于子类对象产生 在每次创建子类对象时,先初始化父类空间,再创建其子类对象本身.目的在于子类对象中包含了其对应的父类空间,便可以包含其父类的成员,如果父类成员非private修饰,则子类可以随意使用父类成员.代码体现在子类的构造方法调用时,一定先调用父类的构造方法. 理解图解如下:  super和this的含义 super :代表父类的存储空间标识(可以理解为父亲的引用). this

  • Java继承extends与super关键字详解

    函数也称为方法! 继承:在java中使用extends关键字来表示继承关系.super用来继承父类方法和参数. 继承就是子类继承父类的特征和行为,使得子类具有父类相同的行为. 注意事项: 1.当一个类没有继承任何一个类时,系统默认继承Object. 2.父类又被称为基类.超类.super类,子类又被称为派生类,这是由于翻译问题而导致的. 3.Java的继承是单一性的. 4.子类不能继承父类的构造方法,但是可以继承构造方法类的参数. 5.子类可以拥有自己的属性和方法,即子类可以对父类进行扩展.但子

  • java多线程编程之Synchronized关键字详解

    本文介绍JAVA多线程中的synchronized关键字作为对象锁的一些知识点. 所谓对象锁,就是就是synchronized 给某个对象 加锁.关于 对象锁 可参考:这篇文章  一.分析 synchronized可以修饰实例方法,如下形式: public class MyObject { synchronized public void methodA() { //do something.... } 这里,synchronized 关键字锁住的是当前对象.这也是称为对象锁的原因. 为啥锁住当

  • Java并发教程之volatile关键字详解

    引言 说到多线程,我觉得我们最重要的是要理解一个临界区概念. 举个例子,一个班上1个女孩子(临界区),49个男孩子(线程),男孩子的目标就是这一个女孩子,就是会有竞争关系(线程安全问题).推广到实际场景,例如对一个数相加或者相减等等情形,因为操作对象就只有一个,在多线程环境下,就会产生线程安全问题.理解临界区概念,我们对多线程问题可以有一个好意识. Jav内存模型(JMM) 谈到多线程就应该了解一下Java内存模型(JMM)的抽象示意图.下图: 线程A和线程B执行的是时候,会去读取共享变量(临界

  • Java Synchronize下的volatile关键字详解

    简介关键词:Synchronize与volatile Synchronize:无论是对于Synchronize同步方法异或是Synchronize块,本质是对某对象或某类加锁,让多线程进行队列化的有序地同步执行. volatile:用于修饰变量.在多线程执行过程中,禁止线程从工作内存(缓存)中读取值. volatile问题抛出: 让我们看到这样一个问题,我们设置一个含有boolean标志位的类Test,以及两个Runable接口实例,分别为MyThread1,MyThread2. 在MyThre

  • Java关键字volatile详析

    目录 一.可见性 二.关于指令重排 volatile关键字关于先说它的两个作用: 保证变量在内存中对线程的可见性 禁用指令重排 每个字都认识,凑在一起就麻了 这两个作用通常很不容易被我们Java开发人员正确.完整地理解,以至于许多同学不能正确地使用volatile 一.可见性 码: public class VolatileTest {     private static volatile int count = 0;     private static void increase() {

  • Java那些鲜为人知的关键字volatile详析

    前言 在Java中,Java中volatile关键字十分重要 本文全面 & 详细解析volatile关键字,希望你们会喜欢 目录 1. 定义 Java 中的1个关键字 / 修饰符 2. 作用 保证 被 volatile修饰的共享变量 的可见性 & 有序性,但不保证原子性 3. 具体描述 下面,我将详细讲解 volatile是如何保证 "共享变量 的可见性 & 有序性,但不保证原子性"的具体原理 储备知识:原子性.可见性 & 有序性 3.1 保证可见性 具

  • Java中final关键字详解

    谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来了解final这个关键字的用法. 主要介绍:一.final关键字的基本用法.二.深入理解final关键字 一.final关键字的基本用法 在Java中,final关键字可以用来修饰类.方法和变量(包括成员变量和局部变量).下面就从这三个方面来了解一下final关键字的基本用法. 1.修饰类 当用final修饰一个类时,表明这个类不能

  • Java中Volatile关键字详解及代码示例

    一.基本概念 先补充一下概念:Java内存模型中的可见性.原子性和有序性. 可见性: 可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉.通常,我们无法确保执行读操作的线程能适时地看到其他线程写入的值,有时甚至是根本不可能的事情.为了确保多个线程之间对内存写入操作的可见性,必须使用同步机制. 可见性,是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的.也就是一个线程修改的结果.另一个线程马上就能看到.比如:用volatile修饰的变量,就会具有可见性.volatile修饰的

随机推荐