目录
目录
1. 修饰符(访问控制)
default: 是不写访问控制符
2. static关键字
2.1 用法
修饰属性、方法等
2.2 static方法
2.2.1 static方法特点
- 被声明为static的成员在内存中只保存了一份,存储在方法区中
- 被声明为static的成员会在类加载的时候加载进内存,而其他非静态成员是在创建对象的时候才会去分配内存
- 被static修饰的成员可以直接通过类名来访问,因为它们不依赖于对象。类名.方法、类名.属性
- 对于一些不常改变的对象可以声明成静态的成员,这样就可以共享这一份资源,而且不会浪费内存
- 一些工具方法适合声明成静态的,因为可以直接拿来调用,更方便,但是不是所有的方法都适合声明成静态的,因为静态成员的生命周期长
- 对于静态变量,可以通过类名和引用来访问,建议通过类名来访问,不建议通过引用来访问
- 静态方法,没有隐式this,所以在静态方法中无法方位实例中的变量,方法。实例方法传入了隐式this,可以访问实例的属性和变量
- 静态方法应用场景: 操作与参数有关于对象无关(对对象属性没有做操作)时,定义为静态方法,例如Arrays.sort()。也就是说static方法的作用在于提供一些"工具方法"和"工厂方法"
2.2.2 案例
package src.basic.language;
import java.util.HashSet;
import java.util.Iterator;
/*
* 这个类主要讲了Static关键字的用法
* */
public class StaticKeywords {
static int paramStatic = 0;
int paramClass;
public static void main(String [] args) {
HashSet<String> set = new HashSet<String>();
set.add("滚滚");
set.add("加油");
set.add("向前滚");
// 对于static的方法、属性,可以不对类进行实例化,也可以调用
StaticKeywords.traverSetWithList(set);
StaticKeywords.traverseWithIterator(set);
// 被声明为static的成员在内存中只保存了一份,如果在一个地方修改了这个静态变量的值,那么其他对象引用这个属性的值也会做对应的修改
/*
* 这里例子省略,可以在备调用的类中声明一个static变量,之后在本类中实例化两个这个类型的变量来做观察
* */
}
public static void traverSetWithList(HashSet <String> set) {
Object [] objs = set.toArray();
for (Object obj : objs) {
System.out.println(obj);
set.add("再滚一次");
}
System.out.println();
}
public static void traverseWithIterator(HashSet <String> set) {
// 在静态方法中,没有饮食的传入this,下面这条语句报错
// this.paramClass = 1;
// 静态属性通过类名.属性来确定
StaticKeywords.paramStatic = 20;
Iterator<String> itr = set.iterator();
while(itr.hasNext()) {
System.out.println(itr.next());
}
System.out.println();
}
public void testStatic() {
this.paramClass = 20;
StaticKeywords.paramStatic = 30;
}
}
2.3 static块
属于类的代码块,在类加载期间执行的代码块,只执行一次,可以用来在软件中加载静态资源
应用场景:
- 常常用于加载静态资源(图片、音频等)
2.3.1 案例
public class StaticKeywords {
// 定义了一个静态块
static {
// 存储在方法区中,在类加载的时候执行的代码块
System.out.println("静态块执行");
}
public static void main(String [] args) {
}
}
// 执行结果
静态块执行
// main函数中没有任何代码,但是还是打印了静态块的语句,说明静态块在所有类实例化之前执行
3. final关键字
final修饰的成员变量以及方法,都不能改变
-
修饰变量:变量不能被改变
- final修饰成员变量的两种方式:
- 声明的同时初始化
- 构造方法中初始化
- final修饰方法变量
- final修饰方法变量时,定义时可以不用赋值,只需要在使用前赋值即可,赋值之后不可修改
- final修饰成员变量的两种方式:
-
修饰方法:方法不能被重写
-
修饰类:类不能被继承,但是可以继承其他类
package src.basic.language;
public class KeyWordsFilnal {
// 声明的同时修饰变量
final int a = 5;
// 声明的同时若没有初始化,要在构造函数中初始化
final int b;
public KeyWordsFilnal() {
// TODO Auto-generated constructor stub
// 构造方法中初始化
b = 10;
}
void finalParam() {
// 在类方法中,
final int c;
// 报错,使用之前要赋值
// System.out.println(c);
c = 6;
// 报错
// c = 7;
}
final void finalMethod() {}
public static void main(String [] args) {
KeyWordsFilnal obj = new KeyWordsFilnal();
}
}
// final的类可以继承其他的类
final class KeyWordsFinalChild extends KeyWordsFilnal{
// 报错,final修饰的方法不能被重写
// void finalMethod() {}
}
// 报错,final修饰的类不能继承
// class KeyWordsFinalGrandChild extends KeyWordsFinalChild{}
4. static final常量
由static final修饰的成员变量成为常量,必须在声明的同时初始化,不可以被改变。由static final修饰的常量会在编译期间被替换。
4.1 规则和建议
- static public修饰的变量必须在声明时就赋值
- 访问static public修饰的常量和static关键字修饰的静态变量相同
- static public修饰的常量不可改变
- 建议常量所有字母都大写
- 在编译时会自动替换为具体的值,相当于C和C++里面的宏,执行效率较高
4.2 案例
package src.basic.language;
class KeywordsStaticFinal {
public static void main(String [] args) {
// 在编译时,程序还未执行前,KeywordsStaticFinal.PI被替换为3.14159
// 这句话和System.out.println(3.14159)是一样的,由于少了一步转换的操作,使用常量程序运行效率更高
System.out.println(KeywordsStaticFinal.PI);
}
public static final double PI= 3.14159;
// 编译错误,static public修饰的变量必须在声明时就赋值
// public staic final int NUM;
}