static是一个关键字,用于定义类、方法、变量和代码块的静态特性。它可以在不同的上下文中使用,并具有不同的含义和功能。
static是静态的意思。 static可以修饰成员变量或者修饰方法。
静态变量(类变量):静态变量在类中用static修饰,被称为静态变量或类变量。
它属于类,而不是实例对象。所有的对象共享该变量的值,且可以直接通过类名访问。静态变量在程序运行期间只会被初始化一次。
定义格式
修饰符 static 数据类型 变量名 = 初始值;
在类中使用`static`关键字修饰变量,即可定义为静态变量。
例子:
public class Car {
static int numberOfCars;
String color;
public Car(String color) {
this.color = color;
numberOfCars++;
}
}
public class Main {
public static void main(String[] args) {
Car car1 = new Car("red");
Car car2 = new Car("blue");
System.out.println(Car.numberOfCars); // 输出:2
}
}
在上面的例子中,Car类中的numberOfCars变量是静态变量,用于统计创建的Car对象数量。通过在Car的构造方法中对numberOfCars进行自增操作,可以实现每创建一个Car对象就增加一辆车的计数。通过Car.numberOfCars可以直接访问该静态变量,并输出结果为2。
访问方式:
静态变量属于类级别,可以通过类名直接访问,也可以通过类的实例访问。
示例代码如下:
public class MyClass {
public static int staticVariable = 10;
}
int x = MyClass.staticVariable;
MyClass obj = new MyClass();
int y = obj.staticVariable;
静态块(静态初始化块): 静态块是一个用static修饰的普通代码块,用于在类加载时执行。
它只会执行一次,并且在类的所有对象之前执行。常用于执行类的静态初始化操作。
定义格式:
public class MyClass {
static {
// 静态块中的代码
}
}
使用`static`关键字定义静态块,静态块中的代码在类加载时执行一次
例子:
public class MathUtils {
static double PI;
static {
PI = 3.14159;
System.out.println("静态块执行");
}
}
public class Main {
public static void main(String[] args) {
System.out.println(MathUtils.PI); // 输出:3.14159
}
}
在上面的例子中,MathUtils类中的静态块用于给静态变量PI赋值,并在执行时输出一条信息。在Main类的main方法中,我们可以直接通过MathUtils.PI访问静态变量PI,输出结果为3.14159。
访问方式:
静态块在类加载时被执行,我们无法在程序中直接访问它。只能通过程序运行过程中访问定义的静态变量、方法或内部类,来触发静态块的执行。
示例代码如下:
public class MyClass {
static {
System.out.println("静态块被执行");
}
}
int x = MyClass.staticVariable;
通过调用静态方法来触发静态块的执行:
MyClass.staticMethod();
通过访问静态内部类来触发静态块的执行:
MyClass.StaticInnerClass obj = new MyClass.StaticInnerClass();
静态方法:静态方法在类中用static修饰,被称为静态方法。
静态方法不依赖于类的实例对象,可以直接通过类名调用。静态方法无法访问非静态的成员变量,只能访问静态的成员变量和调用其他静态方法。
定义格式:
public class MyClass {
public static void staticMethod() {
// 静态方法中的代码
}
}
使用`static`关键字修饰方法,即可定义为静态方法。
例子:
public class MathUtils {
static int add(int a, int b) {
return a + b;
}
}
public class Main {
public static void main(String[] args) {
int result = MathUtils.add(5, 10);
System.out.println(result); // 输出:15
}
}
在上面的例子中,MathUtils类中的add方法是一个静态方法,用于计算两个整数的和。在Main类的main方法中,我们直接通过MathUtils.add方法调用该静态方法,并输出结果为15。
访问方式:
静态方法属于类级别,可以直接通过类名调用,也可以通过类的实例调用。
示例如下:
public class MyClass {
public static void staticMethod() {
// 静态方法中的代码
}
}
MyClass.staticMethod();
MyClass obj = new MyClass();
obj.staticMethod();
静态内部类:当一个类被声明为静态内部类时,它可以被看作是与外部类独立的一个类,不依赖于外部类的实例。
静态内部类可以直接访问外部类的静态成员,并且不能访问外部类的非静态成员。
定义格式:
public class Outer {
static class Inner {
// 静态内部类的成员
}
}
在外部类中使用`static`关键字定义静态内部类。
例子:
public class Outer {
static int outerStaticField;
int outerField;
static class Inner {
void accessOuter() {
System.out.println(outerStaticField);
}
}
}
public class Main {
public static void main(String[] args) {
Outer.Inner inner = new Outer.Inner();
inner.accessOuter(); // 输出:0
}
}
在上面的例子中,Outer类中定义了一个静态内部类Inner。Inner类中的accessOuter方法可以直接访问Outer类的静态成员outerStaticField,并输出结果为0。
访问方式:
静态内部类被声明为类的静态成员,可以通过外部类名来访问。
示例代码如下:
public class Outer {
static class Inner {
// 静态内部类的成员
}
}
Outer.Inner obj = new Outer.Inner();
静态导入:静态导入是指通过使用static import关键字,可以直接导入类的静态成员,而无需使用类名前缀来访问这些静态成员。
定义格式:
import static java.lang.Math.PI;
public class MyClass {
// 使用静态导入后,可以直接使用静态成员 PI
}
使用`import static`语句导入类的静态成员,可以直接使用这些静态成员。
例子:
import static java.lang.Math.PI;
public class Main {
public static void main(String[] args) {
System.out.println(PI); // 输出:3.14159
}
}
在上面的例子中,通过静态导入可以直接使用Math类的静态成员PI,而无需使用Math.PI这样的类名前缀。
访问方式:
静态导入可以直接使用类中的静态成员,无需使用类名限定符。在导入后,使用静态成员的方式与常规的方式相同。
示例代码如下:
import static java.lang.Math.PI;
public class MyClass {
double circumference(double r) {
return 2 * PI * r;
}
}
上例中,静态导入了 java.lang.Math 类中的 PI 常量,可以通过直接使用 PI 来使用这个常量。
静态特性具有以下特点:
静态变量是类级别的变量,所有对象共享它们的值。
静态块用于在类加载时执行初始化操作。
静态方法不依赖于对象的实例,可以直接通过类名调用。
静态内部类与外部类独立,可以直接访问外部类的静态成员。
静态导入可以直接导入类的静态成员,无需使用类名前缀。
关于 static
关键字的使用,它可以用来修饰的成员变量和成员方法,被static修饰的成员是属于类的是放在静态区中,没有static修饰的成员变量和方法则是属于对象的。
当 static
修饰成员变量或者成员方法时,该变量称为静态变量,该方法称为静态方法。该类的每个对象都共享同一个类的静态变量和静态方法。任何对象都可以更改该静态变量的值或者访问静态方法。但是不推荐这种方式去访问。因为静态变量或者静态方法直接通过类名访问即可,完全没有必要用对象去访问。
无static修饰的成员变量或者成员方法,称为实例变量,实例方法,实例变量和实例方法必须创建类的对象,然后通过对象来访问。
static修饰的成员属于类,会存储在静态区,是随着类的加载而加载的,且只加载一次,所以只有一份,节省内存。存储于一块固定的内存区域(静态区),所以,可以直接被类名调用。它优先于对象存在,所以,可以被所有对象共享。
无static修饰的成员,是属于对象,对象有多少个,他们就会出现多少份。所以必须由对象调用。
使用静态关键字(static
)时需要注意以下几点:
静态成员属于类而不是实例。它们被所有对象共享,这意味着一处修改会影响到所有相关的对象。静态方法和变量可以通过类名直接访问,而不需要创建类的实例。
静态变量在类加载时进行初始化,并且只会初始化一次。所有该类的对象共享同一个静态变量的值。
静态方法无法访问非静态成员(变量和方法),因为非静态成员是与对象相关的。但是非静态方法可以访问静态成员。
静态方法不能被重写,但可以被重载。这是因为静态方法与类相关而不是对象相关,所以它们的调用是基于声明类型而不是实际类型。
静态块(static
block)可以在类加载时执行一次。它用于初始化静态成员变量,或执行其他需要在类加载时进行的操作。
静态成员可以是公共的(public
)、私有的(private
)或受保护的(protected
)。这取决于如何访问和使用这些成员。通常情况下,静态成员应该以私有的方式来封装,以避免直接访问和修改。
静态成员可以是常量(final
),这意味着它们的值不能被修改。静态常量通常使用大写字母表示,并且在类的声明中进行初始化。它们通常用作不变的全局配置或常用的常量值。
静态内部类是一个嵌套在另一个类中并被声明为静态的类。静态内部类与外部类的实例无关,并且可以直接访问外部类的静态成员。静态内部类对于将辅助类与其外部类相关联并封装在一起是很有用的。
静态方法可以在没有创建类的对象的情况下调用,这是由于它们只与类本身相关,而不是具体的对象。这使得静态方法适用于实用工具方法,这些方法与该类的对象状态无关。
静态成员的访问具有全局范围。这意味着它们可以被其他类中的任何地方访问,通过使用类名进行限定。