静态和最终的区别?

Tec*_*ner 164 java

我总是staticjava中的final关键字混淆.

他们有什么不同?

ash*_*ish 224

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

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

我们先来看一下静态变量和静态方法.

静态变量

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

静态方法

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

静态类

Java也有"静态嵌套类".静态嵌套类只是一个不隐式引用外部类实例的类.

静态嵌套类可以包含实例方法和静态方法.

在Java中没有顶级静态类.

边注:

main方法是static因为在任何实例化发生之前,应用程序必须是可访问的.

final 在几个不同的上下文中使用关键字来定义以后无法更改的实体.

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

  • final方法不能由子类覆盖.这用于防止子类的意外行为改变可能对类的功能或一致性至关重要的方法.

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

注意:如果变量是引用,则意味着无法重新绑定变量以引用另一个对象.但它引用的对象仍然是可变的,如果它最初是可变的.

当在方法体内定义匿名内部类final时,可以从内部类中访问在该方法范围内声明的所有变量.分配后,最终变量的值不能更改.

  • (我没有向你投票)一些进一步的澄清:"静态方法只能访问静态数据.它不能访问非静态数据(实例变量)" - 除非它有/创建类的实例."静态方法只能调用其他静态方法,不能从中调用非静态方法." - 除非它有/创建了一个类的实例. (5认同)

Jon*_*lor 38

static意味着它属于类而不是实例,这意味着在特定类的所有实例之间只共享该变量/方法的一个副本.

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
Run Code Online (Sandbox Code Playgroud)

final完全不相关,它是一种定义一次初始化的方法.您可以在定义变量时进行初始化,也可以在构造函数中初始化,而不是其他任何地方.

note备注有关最终方法和最终类的注释,这是一种明确声明无法分别覆盖/扩展方法或类的方法.

额外阅读 因此,关于静态的主题,我们讨论了它可能具有的其他用途,它有时用于静态块.使用静态变量时,有时需要在使用类之前设置这些变量,但遗憾的是,您没有获得构造函数.这是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
    }
}
Run Code Online (Sandbox Code Playgroud)

您不能将这与在每个实例的构造函数之前调用的实例初始化程序块混淆.

  • 事情应该是简单明了的。接受的答案只是......冗长。 (4认同)

ars*_*jii 21

两者真的不相似.staticfields是不属于任何特定类实例的字段.

class C {
    public static int n = 42;
}
Run Code Online (Sandbox Code Playgroud)

这里,该static字段nC一般的整个类的任何特定实例都没有关联(这就是为什么C.n可以用它来访问它).你还可以使用C访问的实例n吗?是的 - 但这不是特别好的做法.

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

class C {
    public final int n = 42;
}
Run Code Online (Sandbox Code Playgroud)

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

此外,可以声明类final,表明它们不能扩展:

final class C {}

class B extends C {}  // error!
Run Code Online (Sandbox Code Playgroud)

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

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

class B extends C {
    public void foo() {}  // error!
}
Run Code Online (Sandbox Code Playgroud)


小智 16

最后 -

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

2)当变量值在程序的生命周期内没有改变时,它很有用

静态的 -

1)当我们将" static "关键字应用于变量时,它意味着它属于类.
2)当我们将" static "关键字应用于方法时,意味着可以在不创建类的任何实例的情况下访问该方法


Emm*_*osu 9

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

final关键字只是意味着该值不能改变.没有final,任何对象都可以改变变量的值.


小智 7

简单的差异,

Final:表示变量的值是 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。并且两个 box 都会将 box 的值指定为 6,因为 box2 将 5 的值覆盖为 6。

Final 和 static 是完全不同的。Final是最终的,不能改变。static 它将保持为一但可以更改。

“这是一个例子。记住静态变量总是通过它们的类名来调用。因为它们只是该类的所有对象的一个​​。所以类 A 有 x =5,我可以通过 Ax=6 调用和更改它; ”


小智 5

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

申报

static final String color = "Black"; 
Run Code Online (Sandbox Code Playgroud)

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

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"
}}
Run Code Online (Sandbox Code Playgroud)

注意:现在一旦您将扬声器的颜色更改为 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.
}}
Run Code Online (Sandbox Code Playgroud)

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