final与static比较


(注:该文为《Java程序员面试笔试宝典》中的内容总结)

final

final用于声明属性、方法和类。分别表示属性不可变、方法不可覆盖和类不可被继承。

(1)final 属性:

final修饰的变量不可变。
在这里插入图片描述
从以上的例子中可以看出,final指的是引用的不可变性,即它只能指向初始时指向的那个对象,而不关心指向对象内容的变化。所以,被final修饰的变量必须被初始化。一般可以通过以下几种方式对其进行初始化:

  1. 在定义的时候初始化。
  2. final成员变量可以在初始化块中初始化,但不可在静态初始化块中初始化。
  3. 静态final成员变量可以在静态初始化块中初始化,但不可在初始化块中初始化。
  4. 在类的构造器中初始化,但静态final成员变量不可以在构造函数中初始化。

(2)final 方法:

当一个方法声明为final时,该方法不允许任何子类重写这个方法,但子类仍然可以使用这个方法。另外,还有一种被称为inline(内联)的机制,当调用一个被声明为final的方法时,直接将方法主体插入到调用处,而不是进行方法调用,这样做能提高程序的效率。

(3) final 参数:

用来表示这个参数在这个函数内部不允许被修改。

(4) final 类:

当一个类被声明为final时,此类不能被继承,所有方法都不能被重写。但这并不表示final类的成员变量也是不可改变的,要想做到final类的成员变量不可改变,必须给成员变量增加final修饰。值得注意的是,一个类不能既被声明为abstract,又被声明为final

static

static关键字有两种作用:第一,为某特定数据类型对象分配单一的存储空间,而与创建对象的个数无关。第二,实现某个方法属性与类而不是对象关联在一起,也就是说,在不创建对象的情况下就可以通过类直接调用方法或使用类的属性。具体而言,在Java语言中,static主要有4中使用情况:成员变量、成员方法、代码块和内部类。

(1)static 成员变量

Java提供了两种类型的变量:用static关键字修饰的静态变量和不用static关键字修饰的实例变量。

  1. 静态变量属于类,在内存中只有一个复制(所有实例指向同一个内存地址),只要静态变量所在的类被加载,这个静态变量就会被分配空间,因此就可以被使用了。对静态变量的引用有两种方式,分别为“类.静态变量”和“对象.静态变量”。
  2. 实例变量属于对象,只有对象被创建后,实例变量才会被分配空间,才能被使用,它在内存中存在多个复制。只能用“对象.实例变量”的方式来引用。
public class TestAttribute {
	public static int staticInt = 0;
	public int noStaticInt = 0;

	public static void main(String[] args) {
		TestAttribute t = new TestAttribute();
		System.out.println("t.staticInt = "+ t.staticInt);
		System.out.println("TestAttribute.staticInt = "+ TestAttribute.staticInt);
		System.out.println("t.staticInt = "+ t.noStaticInt);
		System.out.println("对静态变量和实例变量分别加1");
		t.staticInt ++;
		t.noStaticInt ++;
		TestAttribute t1 = new TestAttribute();
		System.out.println("t1.staticInt = "+ t1.staticInt);
		System.out.println("TestAttribute.staticInt = "+ TestAttribute.staticInt);
		System.out.println("t1.staticInt = "+ t1.noStaticInt);

	}
}/* Output:
t.staticInt = 0
TestAttribute.staticInt = 0
t.staticInt = 0
对静态变量和实例变量分别加1
t1.staticInt = 1
TestAttribute.staticInt = 1
t1.staticInt = 0
*///:~

从上例中可以看出,静态变量只有一个,被类拥有,所有对象都共享这个静态变量,而实例变量是与具体对象相关的。需要注意的是,与C++语言不同的是,在Java语言中,不能在方法体中定义static变量。

(2)static 成员方法

Java类同时提供了static方法与非static方法。static方法是类的方法,不需要创建对象就可以被调用,而非static方法是对象的方法,只有对象被创建出来后才可以使用。
static方法中不能使用this和super关键字,不能调用非static方法,只能访问所属类的静态成员变量和成员方法。因为当static方法被调用时,这个类的对象可能还没被创建。
static一个很重要的用途是实现单例模式:

class Singleton{
	private static Singleton instance  = null;
	private Singleton(){}
	public static Singleton getInstance(){
		if(instance == null)
			return new Singleton();
		return instance;
	}
}

(3)static 代码块

static代码块在类中是独立于成员变量和成员函数的代码块。它不在任何一个方法体内,JVM在加载类时会执行static代码块,如果有多个static代码块,JVM将会按顺序来执行。static代码块经常被用来初始化静态变量。需要注意的是,这些static代码块只会被执行一次,示例如下:

public class Test {
	private static int a;
	static {
		Test.a = 4;
		System.out.println(a);
		System.out.println("static block is called");
	}
	public static void main(String[] args) {
	}
}/* Output:
4
static block is called
*///:~

(4)static 内部类

static内部类是指被声明为static的内部类,它可以不依赖于外部类实例对象而被实例化,而通常的内部类需要在外部类实例化后才能实例化。静态内部类不能与外部类有相同的名字,不能访问外部类的普通成员变量,只能访问外部类中的静态成员和静态方法(包括私有类型),示例如下:

public class Outer {
	static  int n=5;
	static class Inner {
		void accessAttrFromOuter(){
			System.out.println("Inner: Outer.n = "+n);
		}
	}
	public static void main(String[] args) {
		Outer.Inner nest = new Outer.Inner();
		nest.accessAttrFromOuter();

	}
}/* Output:
Inner: Outer.n = 5
*///:~

需要注意的是,只有内部类才能被定义为static。

引申

1.什么是实例变量?什么是局部变量?什么是类变量?什么是final变量?

实例变量:变量归对象所有(只有在实例化对象后才可以)。每当实例化一个对象时,会创建一个副本并初始化,如果没有显示初始化,那么会初始化一个默认值。各个对象中的实例变量互不影响。
局部变量:在方法中定义的变量,在使用前必须初始化。
类变量:用static可修饰的属性、变量归类所有,只有类被加载,这个变量就可以被使用(类名.变量名)。所有实例化的对象共享类变量。
final变量:表示这个变量为常量,不能被修改。

2.static与final结合使用表示什么意思?

在Java语言中,static关键字常与final关键字结合使用,用来修饰成员变量成员方法,有点类似于C/C++语言中的“全局变量”。对于变量,若是使用static final修饰,则表示一旦赋值,就不可修改,并且通过类名可以访问。对于方法,若使用static final修饰,则表示该方法不可覆盖,并且可以通过类名直接访问。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值