Java的关键字整理


整理一下不常见的关键字

1. enum关键字

jdk1.5时出现的关键字,用于穷举有限宽度的对象集合(比如说一个星期有且只有七天,性别有且只有男女),用法较多,这里就举个例子。

public class Demo {
	public static void main(String[] args) {
		Sex people = Sex.MALE; //是值,不用new XXXX,直接赋值即可
		switch (people){
			case MALE:
				//.....
				break;
			case FEMAL:
				//......
				break;
		}
		
	}
}

//声明一个枚举,由于都是定值,所以也不需要什么构造函数了(有也可以,也可以像类一样在内部添加方法)
enum Sex{
	MALE, FEMAL;
}

2. final关键字

final关键字可以用于修饰类,方法,对象,参数,特点是修饰之后不能再做改动。

  • 修饰类的时候,这个类不能再被其他类继承。
    在这里插入图片描述

  • 用于修饰方法的时候,子类不允许重写(Override)这个方法。
    在这里插入图片描述

  • 用于修饰对象的时候,不能再修改值。首先区分是八大基本类型还是类

    1. 修饰基本类型的时候,不允许再更改它的值。
      在这里插入图片描述
    2. 修饰类的时候,由于是引用,所以不允许重新引用成其他对象(简单来说就不能再次使用=运算符),但是可以修改其内部数据。
      public static void main(String[] args) {
      	final Test test = new Test();
      	test.string = "111";  //可以运行
      	test = new Test(); //编译不通过
      	}
      	
      class Test{
      	public String string;
      }
      
      在这里插入图片描述
    3. 在使用的时候,可以先不赋值设为空,然后在需要的时候再赋值,不过一旦赋值后不能更改是和之前一样。
      public class Demo {
      	public static void main(String[] args) {
      		final Test test;  //不报错
      		test = new Test(); //不报错
      		test.string = "111";
      		
      		final int i;
      		i = 10; //不报错
      	}
      }
      
      class Test{
      	public String string;
      }
      
  • 修饰参数的时候,同修饰对象 ,不能再修改值。
    在这里插入图片描述

3. finally关键字

常用于异常获取模型中(try/catch),在finally中的代码(语句块)无论是否发生异常,都一定会执行,且执行顺序在最后。

	try{
		String s = null;
		System.out.println("try " + s.toString()); //这行不会输出,因为报错了
	}catch (Exception e){
		System.out.println("catch");
	}finally {
		System.out.println("finally");
	}

catch
finally

	try{
		String s = "s";
		System.out.println("try " + s.toString());
	}catch (Exception e){
		System.out.println("catch");
	}finally {
		System.out.println("finally");
	}

try s
finally

3.1 finally和return

在try/catch语句中,如果在try或者catch代码块中有return语句,finally语句会在return之前先执行。

public static int getNum(){
    
    try{
        return 1;
    }catch (Exception e){

    }
    finally {
        return 2;  //结果是返回2
    }
}

4. instanceof关键字

instanceof是一个操作符,用于判断前一个对象是不是后面一个对象的实例,一般用于if的条件判断中。
用于判断传入的参数是否是某种类的实例。

public static void main(String[] args) {
	Object o = new ArrayList<>();
	judge(o);
}

public static void judge(Object o){
	if (o instanceof ArrayList)	System.out.println("true"); //这个不用多说
	if (o instanceof List)	System.out.println("true"); // implement的类也是true
	if (o instanceof Object)	System.out.println("true"); // extends的类也是true
	if (!(o instanceof Date))	System.out.println("false"); // false
}

5. volatile关键字

Java支持通过使用volatile关键字的办法来进行线程通信,对于声明了volatile的对象而言,它在所有线程中的数据都会保持相等。

  • 声明volatile的对象,每个线程都会相当于从主存获取这个对象的状态。

  • volatile无法保证变量的操作是原子性的,开10个线程,每个线程加1000次,大部分无法达到10000的答案。

public class NoAutoMaticTest {
    public volatile int inc = 0;
     
    public void increase() {
        inc++;
    }
     
    public static void main(String[] args) {
        final NoAutoMaticTest test = new NoAutoMaticTest();
        
        //10个线程对加1000次,本应该得到10000,实际上会因为无法保证变量操作是原子性,经常达不到10000
        //而如果换成synchronized或者lock都可以得到10000
        for(int i=0;i<10;i++){
            new Thread(){
                public void run() {
                    for(int j=0;j<1000;j++)
                        test.increase();
                };
            }.start();
        }
         
        while(Thread.activeCount()>1)  //保证前面的线程都执行完
            Thread.yield();

        System.out.println(test.inc);
    }
}

6. default关键字

这里的default关键字不是指switch语句中的那个default,而是Java8之后才加入的,专门用于接口Interface使用的关键字,当interface中的方法使用default关键字后,可以直接实现其内部的默认功能。

public class test implements interface1{
	public static void main(String[] args){
		//不用实现print方法就可以直接调用
		new test().print();
	}
}

interface interface1{
    default void print(){
        System.out.println("hello default");
    }
}

6.1 default冲突

当一个类同时引用两个接口,而两个接口又拥有同名的default方法时,就会报错,原因是编辑器不知道到底要引用哪一个方法。
在这里插入图片描述
解决方法:

  1. 重写这个默认实现的方法。
    public class test implements interface1, interface2{
    
        @Override
        public void print() {
    
        }
    }
    
  2. 在实现类中指明使用的接口。
    public class test implements interface1, interface2{
    
        @Override
        public void print() {
        	interface1.super.print();
        }
    }
    

7. Serializable关键字

在类的数据要保存到本地或者通过网络传输的时候,这个类就要实现序列化,具体就是implements Serializable。

public class SeriesTest implements Serializable {
    private String name;
    private String id;

    public void setId(String id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }
}

然后序列化用ObjectOutputStream,反序列化用ObjectInputStream。

public class test {
    public static void main(String[] args) {
        //in();
        out();

    }

    public static void in(){
        // 实例化一个对象
        SeriesTest seriesTest = new SeriesTest();
        seriesTest.setId("11");
        seriesTest.setName("name");

        try{
            FileOutputStream fileOut = new FileOutputStream("/tmp/test.txt");
            ObjectOutputStream out = new ObjectOutputStream(fileOut);
            // 写入数据
            out.writeObject(seriesTest);
            out.close();
            fileOut.close();
            System.out.printf("Serialized data is saved in /tmp/test.txt");
        }catch (Exception e){
            e.printStackTrace();
        }

    }

    public static void out(){
        SeriesTest seriesTest = null;
        try
        {
            FileInputStream fileIn = new FileInputStream("/tmp/test.txt");
            ObjectInputStream in = new ObjectInputStream(fileIn);
            // 读取数据
            seriesTest = (SeriesTest)in.readObject();
            in.close();
            fileIn.close();
        }catch(IOException i)
        {
            i.printStackTrace();
            return;
        }catch(ClassNotFoundException c)
        {
            c.printStackTrace();
            return;
        }
        System.out.println("Name: " + seriesTest.getName());
        System.out.println("Id: " + seriesTest.getId());
    }
}

运行in:
Serialized data is saved in /tmp/test.txt
运行out:
Name: name
Id: 11

7.1 transient

被transient声明的成员变量不参与序列化。

public class SeriesTest implements Serializable {
    private String name;
    private transient String id; // 将 id 用transient声明

    public void setId(String id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }
}
运行in:
Serialized data is saved in /tmp/test.txt
运行out:
Name: name
Id: null
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值