java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java关键字

Java几个重要的关键字详析

作者:​ 欣欣子生胖气​

这篇文章主要介绍了Java几个重要的关键字详析,文章围绕主题展开详细的内容介绍,具有一定的参考一下,需要的小伙伴可以参考一下,希望对你的学习有所帮助

1.extends

class Animal{}//父类
class cat extends Animal{}//子类用extends实现继承 

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

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

注意:

2.implements

class Nets implements Clippers,Warriors{}//用implements关键字声明实现了两个接口类

注意:

3.final

使用方法:

使用细节:

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

static final:全局常量

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细节:

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

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

使用步骤:

详细步骤参考

native意义:

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

5.static

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

注意事项:

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

注意事项:

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

好处: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细节

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

注意:

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

7.synchronized

基本介绍:

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

线程同步

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

线程同步机制

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

synchronized使用方法:

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 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执行完毕释放才能调用同步方法

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不能保证原子性,因为不能保证对变量的操作是原子性操作

9.this

10.super

super可以理解为:父类的

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

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

11.访问修饰符

public修饰类:

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

您可能感兴趣的文章:
阅读全文