当先锋百科网

首页 1 2 3 4 5 6 7

1. static关键字

基础概念

1.静态域
表示为类所独有,多个对象共享的区域。因为可以被每一个实例所共享,所以对内存空间是一种很好的节约和性能优化。

2.静态常量

public class  ErrorCode{

    /*--------------------------------登出登出相关--------------------------*/
    
    public static final String USER_NOT_EXSITS="1002";
    public static final String USER_NOT_EXSITS_MSG="用户名不存在";

   }

如上,如果要使用这个常量,直接类.属性就可以使用了,无需每使用一次就创建一个对象,这样对java内存是不是一个很好的性能优化。因为静态变量是属于类的而不是属于对象。

另外补充一下,加上了final关键字,这表明了这个静态变量在调用时不允许被修改,可有效保证了常量的安全性。

注意

1)静态的只能调用静态的,不能调用非静态成员或方法。
因为静态的属于类,而非静态的属于对象,当类被 Java 虚拟机载入的时候,会对 static 变量进行初始化,而对象里面的方法或属性并没有被初始化,只有被new 出实例后才会初始化,所以只能通过对象来使用。

但对象可以直接使用这个类的静态资源。

成员变量和类变量的区别

1、两个变量的生命周期不同
成员变量随着对象的创建而存在,随着对象的回收而释放。
静态变量随着类的加载而存在,随着类的消失而消失,且优先于对象存在。

2、调用方式不同

成员变量只能被对象调用。
静态变量可以被对象调用,还可以被类名调用。

3、数据存储位置不同

成员变量存储在堆内存的对象中,是对象的特有数据。
静态变量数据存储在方法区(共享数据区)的静态区。

2. final关键字

1.final关键字的含义

final在Java中是一个保留的关键字,可以声明成员变量、方法、类以及本地变量。

  • 修饰类:表示类不可被继承
  • 修饰方法:表示方法不可被子类重写,但是可以重载
  • 修饰变量:表示变量一旦被赋值就不可以更改它的值。

(1)修饰成员变量

  • 如果final修饰的是类变量,只能在静态初始化块中指定初始值或者声明该类变量时指定初始值。
  • 如果final修饰的是成员变量,可以在非静态初始化块、声明该变量或者构造器中执行初始值。

(2)修饰局部变量
系统不会为局部变量进行初始化,局部变量必须由程序员显示初始化。
因此使用final修饰局部变量时,即可以在定义时指定默认值(后面的代码不能对变量再赋值),也可以不指定默认值,而在后面的代码
中对final变量赋初值(仅一次)

(3)修饰基本类型数据和引用类型数据

  • 如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;
  • 如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。但是引用的值是可变的。

如一下代码:

public class FinalReferenceTest{ 
public static void main(){ 
final int[] iArr={1,2,3,4}; 
iArr[2]=-3;//合法 
iArr=null;//非法,对iArr不能重新赋值 
final Person p = new Person(25);
 p.setAge(24);//合法 
 p=null;//非法 } 
 }

一旦你将引用声明作final,你将不能改变这个引用了,编译器会检查代码,如果你试图将变量再次初始化的话,编译器会报编译错误。

final关键字的好处

下面总结了一些使用final关键字的好处

1.final关键字提高了性能。JVM和Java应用都会缓存final变量。(读取更快,因为不会被改变所以可以应用缓存。

2.final变量可以安全的在多线程环境下进行共享,而不需要额外的同步开销。(也因为不会改变,所以每个线程读取的都会一样,且无法进行写操作)

3.使用final关键字,JVM会对方法、变量及类进行优化。

思考

1.final和static和的关系

很多时候会容易把static和final关键字混淆,static作用于成员变量用来表示一个类的公有资源,而final的作用是用来保证变量不可变。看下面这个例子:

public class FinalTest {

    public static void main(String[] args)  {
        MyClass myClass1 = new MyClass();
        MyClass myClass2 = new MyClass();
        System.out.println(myClass1.i);
        System.out.println(MyClass.j);
        System.out.println(myClass2.i);
        System.out.println(MyClass.j);

    }
}

class MyClass {
    public final double i = Math.random();
    public static double j = Math.random();
}

运行这段代码就会发现,每次打印的两个j值都是一样的,而i的值却是不同的。从这里就可以知道final和static变量的区别了。

2.为什么局部内部类和匿名内部类只能访问局部final变量?

首先需要知道的一点是: 内部类和外部类是处于同一个级别的,内部类不会因为定义在方法中就会随着方法的执行完毕就被销毁。

这里就会产生问题:当外部类的方法结束时,局部变量就会被销毁了,但是内部类对象可能还存在(只有
没有人再引用它时,才会死亡)。这里就出现了一个矛盾:内部类对象访问了一个不存在的变量。为了解
决这个问题,就将局部变量复制了一份作为内部类的成员变量,这样当局部变量死亡后,内部类仍可以
访问它,实际访问的是局部变量的"copy"。这样就好像延长了局部变量的生命周期
将局部变量复制为内部类的成员变量时,必须保证这两个变量是一样的,也就是如果我们在内部类中修
改了成员变量,方法中的局部变量也得跟着改变,怎么解决问题呢?
就将局部变量设置为final,对它初始化后,我就不让你再去修改这个变量,就保证了内部类的成员变量
和方法的局部变量的一致性。这实际上也是一种妥协。使得局部变量与内部类内建立的拷贝保持一致。

3.finally关键字

1.finally是在retrun语句执行后,return返回之前执行的,也就是说finally必执行(当然是建立在try执行的基础上)。
2.finally中修改的基本类型没有return是不影响返回结果的,有了retrun才会影响
3.finally中修改list ,map,set引用类型时,就算没有return,也是是影响返回结果的

至少有两种情况下finally语句是不会被执行的:

(1)try语句没有被执行到,如在try语句之前就返回了,这样finally语句就不会执行,这也说明了finally语句被执行的必要而非充分条件是:相应的try语句一定被执行到。

(2)在try块中有System.exit(0);这样的语句,System.exit(0);是终止Java虚拟机JVM的,连JVM都停止了,所有都结束了,当然finally语句也不会被执行到。

@see 【漫画】finally到底是在return之前执行还是return之后执行? https://www.jianshu.com/p/841c63511b74

4.this关键字

表示当前对象的句柄如:hello.java文件this表示的则为hello类,且this不能在static修饰的方法中使用.

5.Native关键字

简单地讲,一个Native Method就是一个java调用非java代码的接口。一个Native Method是这样一个java的方法:该方法的实现由非java语言实现,比如C。这个特征并非java所特有,很多其它的编程语言都有这一机制,比如在C++中,
你可以用extern "C"告知C++编译器去调用一个C的函数。

6.transient 关键字

被transient 修饰的变量,将不能被系列化

7.instanceof关键字

instanceof是Java的一个二元操作符(运算符),也是Java的保留关键字。它的作用是判断其左边对象是否为其右边类的实例,返回的是boolean类型的数据。用它来判断某个对象是否是某个Class类的实例或是否实现某个接口。

如:
1.判断是否实现某个接口

 ArrayList list = new ArrayList();
 System.out.println(list instanceof List);

参考文献

1.http://www.importnew.com/7553.html
2.浅析Java中的final关键字https://www.cnblogs.com/dolphin0520/p/3736238.html
3.书籍《core java》
4.【漫画】finally到底是在return之前执行还是return之后执行? https://www.jianshu.com/p/841c63511b74