static关键字最基本的用法是:
静态变量是类变量,可以通过类名进行修改。变量名直接被引用,而不需要创建一个新类
2. 静态方法属于类方法。直接引用方法名,而不需要创建新类
静态变量和方法是类的静态资源,它们在类实例之间共享。JDK将不同的静态资源放在不同的类中,而不是将所有静态资源放在一个类中。你们很多人可能会想,当然你想这么做,但你有没有想过为什么?就我个人而言,有三个主要好处:
1. 不同的类有自己的静态资源,可以实现静态资源分类。Math中的Math静态资源和java.util.calendar中的Calendar静态资源是清晰的
避免使用相同的名字。在不同的类之间,静态变量名和静态方法名具有相同的名称也是很常见的。当你把所有东西放在一起,不可避免地得到重复的名字时,会发生什么?把它解决掉。
3.避免静态资源类的无限扩展是有意义的。
好了,再深入一点,这是另一个让一些人困惑的问题:静态方法是否可以引用非静态资源?静态方法可以引用静态资源吗?非静态方法可以引用静态资源吗?例如,这段代码有什么问题吗?
public class A
{
private int i = 1;
public static void main(String[] args)
{
i = 1;
}
}
当然有错误。在7号线。这样想:
静态资源属于类,但独立于类而存在。从JVM的类加载机制的角度来看,静态资源是在类初始化时加载的,而不是在类新建时加载静态资源。类初始化先于类新建,例如类。forname (" XXX ")方法,它在不使用new的情况下初始化一个类,只是加载类的静态资源。所以对于静态资源,不可能知道类中有哪些非静态资源;但对于非静态资源则不是这样,因为它是在new之后创建的,所以它知道属于类的所有东西。所以这些问题的答案很清楚:
1. 静态方法可以引用非静态资源吗?不,当它是新的时,它不知道在初始化后存在的静态资源的任何东西。
2. 静态方法可以引用静态资源吗?是的,因为它是在类初始化时加载的,而且每个人都知道彼此。
3.非静态方法可以引用静态资源吗?是的,非静态方法是一个实例方法,它在new之后,所以它知道属于类的所有东西。
public class A
{
private static int a = B();
static
{
System.out.println("Enter A.static block");
}
public static void main(String[] args)
{
new A();
}
public static int B()
{
System.out.println("Enter A.B()");
return 1;
}
}
打印结果为:
Enter A.B() Enter A.static block
得出第一个结论:静态资源的加载顺序是严格按照静态资源的定义顺序来加载的。这和周志明老师《深入理解Java虚拟机:JVM高级特性与最佳实践》中类初始化中的说法“
再看一个例子:
public class A
{
static
{
c = 3;
System.out.println(c);
}
private static int c;
}
这段代码的第六行有一个错误“不能在定义字段之前引用它”。从这个例子得出的第二个结论是,静态代码块可以被赋值给它后面定义的静态变量,但不能被访问。
最后一个小例子:
public class A
{
static
{
System.out.println("A.static block");
}
public A()
{
System.out.println("A.constructor()");
}
}
public class B extends A
{
static
{
System.out.println("B.static block");
}
public B()
{
System.out.println("B.constructor()");
}
public static void main(String[] args)
{
new B();
new B();
}
}
A.static block B.static block A.constructor() B.constructor() A.constructor() B.constructor()
这个例子引出了第三个结论:静态代码块是严格遵循其超类->子类静态代码块按顺序加载,且只加载一次。
静态修饰符类
Static不修改类。如果static修改了一个类,那么这个类就是一个匿名内部类。ThreadPoolExecutor、callerrunpolicy、AbortPolicy、DiscardPolicy和DiscardOldestPolicy中的四种拒绝机制是静态内部类。静态内部类将在编写内部类时介绍。
静态导入
这是一个闭塞的地方,你很少看到它在任何地方使用。您可以在JUnit中使用它,但是编写断言更容易。导入静态是JDK1.5之后的一个新特性。这两个关键字可以一起使用,在不使用类名的情况下指定在类中导入指定的静态资源。资源名称。您可以直接使用资源名。注意,import static必须以这种方式编写,而不是作为static import。这里有一个例子:
import static java.lang.Math.*;
public class A
{
public static void main(String[] args)
{
System.out.println(sin(2.2));
}
}
这意味着我已经在Math下导入了所有静态资源,我可以在main中使用sin(2.2)而不是Math。罪(2.2)。Math:导入静态java.lang.Math。* * * = import static java.lang.Math * = import static java.lang.Math。当然,我们可以指定只导入一个静态资源,比如只导入Math下的sin方法,而不导入Math下的所有静态资源:
import static java.lang.Math.sin;
public class A
{
public static void main(String[] args)
{
System.out.println(sin(2.2));
}
}
我可以这样写。导入静态变量也是如此,如果您感兴趣,可以自己尝试一下。对于import static,我个人的态度是:
1. 简化了诸如静态导入Math下的所有静态资源的操作,大大减少了Math下经常使用的静态资源的操作。
2. 减少了代码的可读性
建议在特定场景下导入特定的静态资源。不建议使用。*模式。
想要系统学习JAVA推荐JAVA300集
Java300集零基础适合初学者视频教程https://www.bilibili.com/video/BV1oy4y1H7R6?spm_id_from=333.999.0.0



