static关键字:可以用于修饰属性,方法,类。
在Java中,可以将一些成员限制为和类相关的,而不是和实例相关的。实现这个目的的方法是,在类的成员如方法、属性乃至自由代码块前面加上“static”这个修饰符。
实例变量用于描述单个实例的状态,而类变量用于描述类的状态,和具体的实例无关。
实例方法用于操作实例变量并维护特定实例的状态,而类方法并不了解单个实例的状态。
在Java中,static最常用的地方是用在Java应用程序的入口方法main()前面用于修饰main()方法,表示main()方法是一个类方法。
我们在执行一个应用程序的时候,解析器将会去寻找这个main()方法,之所以将它设置为类方法,是因为,在调用这个main()方法之前,还没有任何对象存在,所以,如果不将它设置为类相关的,则没有办法得到任何的对象,也就无法调用这个main()方法。
我们来看另外一个static的例子:
public class TestStatic {
public static int count=0;
public TestStatic() {
count++;
}
public static int getCount() {
return count;
}
public static void main(String args[]) {
TestStatic ts1=new TestStatic();
System.out.println(ts1.count);
TestStatic ts2=new TestStatic();
System.out.println(ts2.count);
//System.out.println(TestStatic.count);
//System.out.println(TestStatic.getCount());
}
}
在这个程序中,定义了一个静态变量count,并定义了一个静态方法来获取。每次在构造这个类的实例的时候,都将这个count加上1。
因为这个变量是类变量,所以,每次在调用构造方法来构造类的实例的时候,都会将这个变量加上1。因为它是和类相关的,所以,它会在原来的基础上加上1,而不是每次都对它进行初始化成0。
运行这个程序,将得到如下的结果:
1
2
如果将这个程序的静态变量count和静态方法getCount()都改成非静态的(只需将变量和方法前的static都去掉),重新编译运行,则可以得到下面的结果:
1
1
这是因为,如果将静态变量count前的static去掉,则这个变量变成了非静态变量,也就是实例变量,这样,每次调用构造器进行类的实例化时,将重新对这个变量进行初始化,因此,每次它都是从0开始计算,然后在构造器中对其加1,这样,打印出来的结果就是1了。
在这个程序中,也可以不通过实例名来访问变量count或方法getCount(),因为这两个成员都是类成员,可以直接通过类名加“.”来调用它们。将程序中的两个打印语句的注释去掉,就可以向控制台输出如下的结果:
1
2
2
2
最后需要指出的是,static不可用于修饰构造器。
注意:虽然static修饰的成员是类成员,但是,同样可以通过实例名来调用static修饰的类成员,就像调用其他的实例成员一样。
接下来讲讲static自由块。
前面提到了自由块(游离块),那么作为Java源代码特殊的组成部分,是可以用static来修饰的。修饰后的结果我们来分析下。
自由块可以看成是一种特殊的方法,这个方法没有方法名、没有输入参数、没有返回值,不能进行方法调用。从这个角度来看,在自由块前面也可以加上static关键字来修饰。这样,这个自由块就成了静态自由块。静态自由块通常用于初始化静态变量。
public class Count {
private int serialNumber;
public static int counter;
static {
System.out.println("static自由块被执行");
counter = 1;
}
public static int getTotalCount() {
return counter;
}
public Count() {
counter++;
serialNumber = counter;
}
public static void main(String[] args) {
System.out.println("main() invoked");
System.out.println("counter = " + Count.counter);
}
}
在这个类中,定义了一个静态的int类型变量counter,然后在static自由块中初始化这个变量。编译并运行这个程序,可以得到如下的输出:
static自由块被执行
main() invoked
counter = 1
因为static自由块是类相关而不是实例相关的,所以,即使没有实例化对象,它也会被执行(在main()方法中没有实例化这个类)----它将向控制台输出“static自由块被执行”并将静态变量“counter”初始化成1。
static修饰属性:无论一个类生成了多少个对象,所有这些对象共同使用唯一一份静态的成员变量;一个对象对该静态成员变量进行了修改,其他对象的该静态成员变量的值也会随之发生变化。如果一个成员变量是static的,那么我们可以通过“类名.成员变量名”的方式来使用它(推荐使用这种方式)。[Class012/StaticVariable.java]
static修饰方法:static修饰的方法叫做静态方法。对于静态方法来说,可以使用类名.方法名的方式来访问。[Class012/StaticMethod.java]
静态方法只能继承,不能重写(Override)。【难点】
[Class012/StaticMethodOverwrite.java]
静态方法可以通过二种形式来调用,一种是类名加方法名,另一种是类引用加方法名.通过第二种方式来调用静态方法,其实质是检查引用的类型来调用静态方法(即类名加方法名的方式).
静态成员(方法和属性)属于类而不是属于对象,静态方法,静态属性,动态属性早在编译期就已经确定(相关地址数据存储在虚拟机的方法区类数据中).
1. 静态方法可以被继承
程序一:
import static java.lang.System.out;
class SuperClass
{
publicstatic void display()
{
out.println("inthe super class.");
}
}
public class SubClass extends SuperClass
{
publicstatic void main(String[] args)
{
SubClasssub = new SubClass();
sub.display(); // 调用子类继承父类的静态方法
}
}
根据输出结果:
in the super class.可知 sub.display() 调用子类继承了父类的静态方法.由此可见,子类可以继承父类的静态方法.
2. 静态方法被隐藏不能被重写
程序二:
import static java.lang.System.out;
class SuperClass
{
publicstatic void display()
{
out.println("inthe super class.");
}
}
public class SubClass extends SuperClass
{
publicstatic void main(String[] args)
{
SubClasssub = new SubClass(); // 上转型对象
sub.display(); // 调用子类自己的静态方法
SuperClasssup = new SubClass(); // 子类对象
sup.display(); // 用被隐藏的父类静态方法
}
publicstatic void display()
{
out.println("inthe sub class.");
}
}
运行结果:
----------------------------
in the sub class.
in the super class.
----------------------------
对于动态方法,上转型对象调用的将会是子类中重写父类的动态方法.而对于此处的静态方法,父类子类中都含有静态方法display()的情况,上转型对象却调用的父类的静态方法display(),而非子类中定义的静态方法display().
由此可见:子类并没有重写父类的静态方法,而是将父类的静态方法隐藏,隐藏的父类方法可以通过父类类名在子类中被调用.当子类中重写的方法也是静态的时候,其实质是将父类的
静态方法隐藏,而并非是将其重写.
隐藏和重写的区别在于:隐藏是根据引用的类型来进行调用.重写是根据对象的类型来进行调用.
3. 动态方法不能覆盖静态方法
上述程序二,如果去掉子类方法display()的static修饰,则会报如下错误:
---------- 编译Java ----------
报错:
SubClass 中的 display() 无法覆盖 SuperClass 中的 display();
被覆盖的方法为 staticpublic void display()
说明: 子类中的动态方法display()无法覆盖父类中的静态方法display().
4. 静态方法不能覆盖动态方法
上述程序二,如果去掉父类方法display()的static修饰,则会报如下错误:
---------- 编译Java ----------
报错:
SubClass 中的 display() 无法覆盖 SuperClass 中的 display();
覆盖的方法为静态public static void display()
说明: 子类中的静态方法display()无法覆盖父类中的动态方法display().
2. final关键字:final可以修饰属性、方法、类。
final修饰类:当一个类被final所修饰时,表示该类是一个终态类,即不能被继承。
[Class012/FinalClass.java]
final修饰方法:当一个方法被final所修饰时,表示该方法是一个终态方法,即不能被重写(Override)。[Class012/FinalMethod.java]
final修饰属性:当一个属性被final所修饰时,表示该属性不能被改写。当final修饰一个原生数据类型时,表示该原生数据类型的值不能发生变化(比如说不能从10变为20);
如果final修饰一个引用类型时,表示该引用类型不能再指向其他对象了,但该引用所指向的对象的内容是可以发生变化的。[Class012/FinalProperty.java]
对于final类型成员变量,一般来说有两种赋初值方式:
a) 在声明final类型的成员变量时就赋上初值
b) 在声明final类型的成员变量时不赋初值,但在类的所有构造方法中都为其赋上初值。
[Class012/FinalData.java]
3.static代码块:静态代码块。静态代码块的作用也是完成一些初始化工作。
首先执行静态代码块,然后执行构造方法。静态代码块在类被加载的时候执行,而构造方法是在生成对象的时候执行;要想调用某个类来生成对象,首先需要将类加载到Java虚拟机上(JVM),然后由JVM加载这个类来生成对象。
类的静态代码块只会执行一次,是在类被加载的时候执行的,因为每个类只会被加载一次,所以静态代码块也只会被执行一次;而构造方法则不然,每次生成一个对象的时候都会调用类的构造方法,所以new一次就会调用构造方法一次。
如果继承体系中既有构造方法,又有静态代码块,那么首先执行最顶层的类的静态代码块,一直执行到最底层类的静态代码块,然后再去执行最顶层类的构造方法,一直执行到最底层类的构造方法。注意:静态代码块只会执行一次。
[Class012/StaticBlock.java]
[Class012/StaticBlockInherit.java]
4.不能在静态方法中访问非静态成员变量;可以在静态方法中访问静态的成员变量。可以在非静态方法中访问静态的成员变量。
[Class012/StaticProperty.java]
5. 总结:静态的只能访问静态的;非静态的可以访问一切。
6. 不能在静态方法中使用this关键字。
[Class012/ StaticProperty.java]
相关推荐
在 Java 编程语言中,final 和 static 是两个非常重要的关键字,它们可以用来修饰类、方法、变量等,了解它们的使用方法和限制非常重要。本文将详细总结 final 和 static 的使用方法和限制。 一、final 关键字 ...
Java中的`final`和`static`关键字是编程中非常重要的两个修饰符,它们分别用于不同的场景,以确保代码的稳定性和高效性。 首先,`final`关键字主要用于表示不可变性。它可以用来修饰类、方法和变量。对于类,如果一...
`static`关键字在Java中主要用于创建静态成员,包括静态变量和静态方法。与普通成员不同,静态成员属于类级别,而不是实例级别。这意味着无论创建了多少个类的实例,静态成员只有一个副本存在于内存中。 #### 二、...
Java编程中static和final关键字的陷阱.pdf Java编程中static和final关键字的陷阱是Java开发中两个重要的关键字,但是它们的使用也存在一些陷阱,需要开发者注意掌握。 static关键字可以用于修饰属性、方法和类。...
面向对象部分让人搞晕的几个关键字,我这里专门针对这几个关键字进行了整理相关的面试题,只要你能做对80%,就证明你面向对象基本学懂了
Java 中 static、this、super、final 的用法 静态方法(static method)是一种特殊的方法,它可以在不需要创建...static、this、super、final 是 Java 中四个非常重要的关键字,了解它们的用法是 Java 编程的基础。
第二十二天,对抽象类,static关键字以及final关键字的学习
Java 中的 static 关键字是用于声明类的成员变量和成员方法的,它可以使得变量和方法属于类本身,而不属于某个对象。静态变量也称为类变量,静态方法也称为类方法。静态变量和静态方法可以直接通过类名调用,不需要...
Java 中的 final 和 static 关键字详解 final 关键字是 Java 中的一种访问修饰符,用于修饰类、方法和变量,以确保它们不能被修改或继承。下面是 final 关键字的详细解释: 1. final 类 final 类不能被继承,也...
在Java编程语言中,`static`和`final`都是关键字,它们用于定义不同的特性,但同时也有一些相似之处。下面我们将详细探讨这两个关键字的区别和用法。 首先,`static`关键字是用来声明类级别的变量或方法,这意味着...
Java编程中的`static`关键字和`final`关键字是两个非常重要的概念,它们分别代表不同的特性。首先,我们来看`static`关键字。 `static`关键字用于声明静态变量和静态方法。静态变量,也称为类变量,属于类本身而...
此外,`final`关键字还有其他用途,如`final`修饰的匿名内部类和`final`局部变量在匿名内部类中的特殊规则,以及`final`与`static`结合时的静态常量等。理解并熟练应用`final`关键字对于编写高效、安全的Java代码至...
在Java编程语言中,`static`、`final`、`abstract`和`interface`是四个非常重要的关键字,它们分别代表不同的特性,用于定义类、变量和方法的行为。下面是对这些关键字的详细解释: 1. **static(静态)** - **...
Static、Final 和 Static Final 是 Java 中三个重要的关键字,它们之间的区别和应用场景是开发者需要了解和掌握的。 首先,让我们来了解 Static 关键字。Static 是 Java 中的静态修饰符,可以修饰变量、程序块、...
Java多线程关键字final和static详解 Java多线程编程中,final和static关键字扮演着非常重要的角色,它们可以帮助开发者编写更加安全、可靠的多线程程序。在本文中,我们将深入探讨final和static关键字在Java多线程...
### Static (静态) 和 Final (最终) 在 Java 中的应用 ...通过上述讨论可以看出,`static` 和 `final` 这两个关键字在 Java 中有着重要的作用,合理使用它们可以提高代码的质量、安全性和可维护性。
在Java编程语言中,`final`与`static`是两个非常关键且常用的关键字,它们各自具有独特的功能和用途,可以极大地增强代码的稳定性和可维护性。下面将详细解析这两个关键字的用法及其在Java中的重要性。 ### 一、`...
在Java编程语言中,`final` 和 `static` 是两个非常重要的关键字,它们分别具有不同的含义和用法,但都对代码的结构和行为产生深远影响。本文将深入探讨这两个关键字,并结合实际示例来解释它们的应用场景。 首先,...
Java 中的 final 和 static 关键字详解 Java 中的 final 和 static 关键字是两个重要的关键字,它们在 Java 编程中扮演着重要的角色。本文将详细介绍 final 和 static 关键字的使用方法和注意事项。 一、final ...