静态和最终的区别?

我总是在staticfinal关键字之间混淆Java

他们有什么不同?

307130 次浏览

静态是类中的任何对象都可以调用的东西,它本质上属于对象类型。

对于整个类来说,变量可以是final的,这仅仅意味着它不能再被更改。它只能设置一次,再次尝试设置将导致抛出错误。它很有用,原因有很多,也许你想声明一个不能改变的常量。

一些示例代码:

class someClass
{
public static int count=0;
public final String mName;


someClass(String name)
{
mname=name;
count=count+1;
}


public static void main(String args[])
{
someClass obj1=new someClass("obj1");
System.out.println("count="+count+" name="+obj1.mName);
someClass obj2=new someClass("obj2");
System.out.println("count="+count+" name="+obj2.mName);
}
}

Wikipedia包含Java关键字的完整列表。

静态的表示它属于类而不是实例,这意味着该变量/方法只有一个副本在特定班级的所有实例之间共享。

public class MyClass {
public static int myVariable = 0;
}


//Now in some other code creating two instances of MyClass
//and altering the variable will affect all instances


MyClass instance1 = new MyClass();
MyClass instance2 = new MyClass();


MyClass.myVariable = 5;  //This change is reflected in both instances

最后的是完全无关的,它是一种定义一次性初始化的方法。您可以在定义变量时进行初始化,也可以在构造函数中进行初始化,而不是在其他地方。

注意关于final方法和final类的说明,这是一种显式声明方法或类不能分别被覆盖/扩展的方法。

额外阅读 关于静态的话题,我们讨论了它可能具有的其他用途,它有时用于静态块。使用静态变量时,有时需要在使用类之前设置这些变量,但不幸的是,您没有获得构造函数。这就是static关键字的用武之地。

public class MyClass {


public static List<String> cars = new ArrayList<String>();


static {
cars.add("Ferrari");
cars.add("Scoda");
}


}


public class TestClass {


public static void main(String args[]) {
System.out.println(MyClass.cars.get(0));  //This will print Ferrari
}
}

您不能将其与实例初始化程序块混淆,后者是在构造函数每一 instance之前调用的。

这两者实际上并不相似。static字段是不属于类的任何特定实例的字段。

class C {
public static int n = 42;
}

这里,static字段n不与C的任何特定实例相关联,而是通常与整个类相关联(这是C.n可用于访问它的原因)。您是否仍可以使用C的实例来访问n?是的-但它不被认为是特别好的做法。

另一方面,final表示特定变量在初始化后不能更改。

class C {
public final int n = 42;
}

这里,n不能被重新分配,因为它final。另一个区别是,任何变量都可以声明为final,而不是每个变量都可以声明为STATIC.

另外,类可以final来声明,这表示它们不能被扩展:

final class C {}


class B extends C {}  // error!

类似地,可以将方法声明为final,以指示它们不能被扩展类被推翻

class C {
public final void foo() {}
}


class B extends C {
public void foo() {}  // error!
}

Static和Final有一些很大的区别:

静态变量或类总是可以从(几乎)任何地方获得。Final只是一个关键字,表示变量不能更改。所以如果有:

public class Test{
public final int first = 10;
public static int second = 20;


public Test(){
second = second + 1
first = first + 1;
}
}

程序将一直运行,直到它试图更改“第一个”整数,这将导致错误。在这个类之外,如果您已经实例化了这个类,那么您只能访问“第一个”变量。这与“秒”形成对比,“秒”是随时可用的。

static关键字可以在4个场景中使用

  • 静态变量
  • 静态方法
  • 静态代码块
  • 静态嵌套类

我们先来看看静态变量和静态方法。

静态变量

  • 它是属于类而不是对象(实例)的变量。
  • 静态变量只在开始执行时初始化一次。在初始化任何实例变量之前,将首先初始化这些变量。
  • 由类的所有实例共享的单个副本。
  • 静态变量可以通过类名直接访问,不需要任何对象。
  • 语法:Class.variable

静态法

  • 它是一个属于类而不属于对象(实例)的方法。
  • 静态方法只能访问静态数据。它不能访问非静态数据(实例变量),除非它具有/创建类的实例。
  • 静态方法只能调用其他静态方法,并且不能从中调用非静态方法,除非它具有/创建类的实例。
  • 静态方法可以通过类名直接访问,不需要任何对象。
  • 语法:Class.methodName()
  • 静态方法无论如何都不能引用thissuper关键字。

静态类

Java还有“静态嵌套类”。静态嵌套类只是一个没有隐式引用外部类实例的类。

静态嵌套类可以有实例方法和静态方法。

Java中没有所谓的顶级静态类。

旁注:

Main方法是ABC_0的_,因为在任何实例化发生之前,它必须是可访问的,应用程序才能运行。

final关键字用于几个不同的上下文中,以定义以后不能更改的实体。

  • final类不能再分类。这样做是出于安全和效率的原因。因此,许多Java标准库类是final,例如java.lang.Systemjava.lang.Stringfinal类中的所有方法都隐式final

  • final方法不能被子类重写。这是用来防止子类的意外行为,改变可能对类的功能或一致性至关重要的方法。

  • final变量只能通过初始值设定项或赋值语句初始化一次。它不需要在声明时进行初始化:这称为blank final变量。一个空白的类的最后一个实例变量必须在声明它的类的每个构造函数的末尾明确地赋值。类似地,空的final静态变量必须在声明它的类的静态初始化器中明确地赋值。否则,在这两种情况下都会发生编译时错误。

注意:如果变量是一个引用,这意味着变量不能被重新绑定以引用另一个对象。但是它引用的对象仍然是可变的,如果它最初是可变的。

当在方法体内定义匿名内部类时,在该方法范围内ABC_0_声明的所有变量都可以从内部类中访问。一旦被赋值,final变量的值就不能改变。

我不会在这里给出一个完整的答案。我的建议是专注于理解它们中的每一个的作用,然后应该清楚地看到它们的效果是完全不同的,以及为什么有时它们一起使用。

static用于类的成员(属性和方法),并且必须将其理解为与实例(非静态)成员相反。我推荐阅读Java教程中的“了解实例和类成员”。我也可以在_中使用ABC_0块,但我不会担心它的开始。

final根据其应用于变量、方法、类或其他情况而具有不同的含义。在这里,我更喜欢维基百科解释

想象一个物体,比如一个扬声器。如果扬声器是一个类,它将有不同的变量,如音量,高音,低音,颜色等。您可以在定义Speaker类时定义所有这些字段。例如,您使用静态修饰符声明了颜色字段,这意味着您告诉编译器该变量只存在一个副本,而不管该类被实例化了多少次。

声明

static final String color = "Black";

将确保无论何时实例化此类,颜色字段的值都将为“黑色”,除非它未更改。

public class Speaker {


static String color = "Black";


}


public class Sample {


public static void main(String args[]) {
System.out.println(Speaker.color); //will provide output as "Black"
Speaker.color = "white";
System.out.println(Speaker.color);  //will provide output as "White"
}}

注意:现在,一旦您将扬声器的颜色更改为final,此代码将不会执行,因为final关键字确保字段的值永远不会更改。

public class Speaker {


static final String color = "Black";


}


public class Sample {


public static void main(String args[]) {
System.out.println(Speaker.color); //should provide output as "Black"
Speaker.color = "white"; //Error because the value of color is fixed.
System.out.println(Speaker.color); //Code won't execute.
}}

您可以将此代码直接复制/粘贴到您的模拟器中并尝试。

最后的-

1)当我们将“最后的 ”关键字应用于变量时,该变量的值保持不变。 (或) 一旦我们将变量声明为最后的,该变量的值就不能改变。

2)当变量值在程序寿命期间不改变时,这是有用的。

静态-

1)当我们将“静态的 ”关键字应用于变量时,表示它属于类。
2)当我们将“静态的 ”关键字应用于方法时,这意味着可以访问方法,而无需创建该类

的任何实例

static表示在类的所有实例共享的内存中只有一个变量副本。

final关键字仅表示该值不能更改。如果没有final,则任何对象都可以更改该变量的值。

静态变量值可以在变量的一个副本遍历应用程序时更改,而最终变量值可以初始化一次,并且不能在整个应用程序中更改。

容易的差异,

最后的:表示变量的值是最终的,它不会在任何地方改变。如果你说最终的X=5,这意味着X不能改变,它的值对每个人来说都是最终的。

静态的:表示它只有一个对象。让我们假设你有X=5,在内存中有X=5,并且它存在于一个类中。如果你创建一个类的对象或实例,这意味着有一个特定的框来表示该类及其变量和方法。如果你创建了这个类的另一个对象或实例,这意味着在内存中有两个相同类的盒子,里面有不同的X.如果你在不同的位置调用两个X并改变它们的值,那么它们的值就会不同。盒子1有X,其中X=5,盒子2有X=6。但如果您将X设置为静态,则意味着无法再次创建它。 您可以创建类的对象,但该对象中不会有不同的X. 如果X是静态的,那么框1和框2都将具有相同的X,其值为5。是的,我可以在任何地方更改静态的值,因为它不是最终的。所以如果我说盒子1有X,我把它的值改为X=5,然后我做了另一个盒子,它是盒子2,我把盒子2的值X改为X=6。然后,由于X是静态的,两个框具有相同的X.并且两个框都将给出框的值为6,因为框2将值5覆盖为6。

最终和静态是完全不同的。最终版是最终版,不能更改。静态,将保持为一个,但可以更改。

这是一个例子。记住,静态变量总是用它们的类名来调用。因为对于该类的所有对象,它们只有一个。所以 类A有X=5,我可以通过A.X=6调用并改变它;