静态和最终的区别?

我一直在Java中的 staticfinal关键字之间混淆。

他们有什么不同?

static关键字可以用于4个场景

  • 静态variables
  • 静态方法
  • 静态的代码块
  • 静态嵌套类

我们先来看静态variables和静态方法。

静态variables

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

静态方法

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

静态类

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

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

Java中没有这样的顶级静态类。

边注:

main方法是static因为它必须是可以访问的,以便在任何实例化之前运行应用程序。

在几个不同的上下文中使用final关键字来定义一个以后不能改变的实体。

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

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

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

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

当一个匿名内部类被定义在一个方法体内时,所有在该方法范围内声明为finalvariables都可以从内部类中访问。 一旦分配完毕,最终variables的值就不能改变。

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

 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是完全不相关的,它是定义一次只初始化的一种方式。 您可以在定义variables时或在构造函数中进行初始化,在其他地方无法进行初始化。

注意关于最终方法和最终类的说明,这是明确指出方法或类不能被重写/扩展的一种方法。

额外阅读所以关于静态的话题,我们正在谈论它可能有的其他用途,它有时用在静态块中。 当使用静态variables时,有时需要在使用类之前设置这些variables,但不幸的是,您不会得到构造函数。 这是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 } } 

你不能把它与在每个实例的构造函数之前调用的实例初始化块混淆。

这两个真的不相似。 static字段是不属于某个类的任何特定实例的字段。

 class C { public static int n = 42; } 

在这里, static字段n不与C任何特定实例相关联,而是与整个类相关联(这就是为什么可以使用Cn来访问它)。 你还能用C一个实例来访问n吗? 是的 – 但这不被认为是特别好的做法。

final另一方面表明特定variables在初始化后不能改变。

 class C { public final int n = 42; } 

在这里, n不能被重新分配,因为它是final 。 另一个区别是任何variables都可以声明为final ,而不是每个variables都可以声明为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! } 

最后 –

1)当我们将“ final ”关键字应用于variables时 ,该variables的值保持不变。 (或)一旦我们声明一个variablesfinal ,那个variables的值就不能改变。

2)在程序生存期间, variables值不变的情况下有用

静态的 –

1)当我们将“ 静态 ”关键字应用于variables时 ,这意味着它属于类。
2)当我们将“ 静态 ”关键字应用到一个方法时 ,这意味着该方法可以被访问而不需要创build任何类的实例

静态和最终有一些很大的区别:

静态variables或类将始终可用(几乎)任何地方。 最终只是一个关键字,意味着一个variables不能改变。 所以如果有:

 public class Test{ public final int first = 10; public static int second = 20; public Test(){ second = second + 1 first = first + 1; } } 

该程序将运行,直到它试图改变“第一个”整数,这将导致一个错误。 在这个类之外,如果你已经实例化了这个类,那么你只能访问“第一个”variables。 这与“秒”形成鲜明对比,而“秒”则始终可用。

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

声明

 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关键字可确保该字段的值永远不会更改。

 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. }} 

你可以直接复制/粘贴这个代码到你的模拟器中,然后尝试。

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

一个variables对于一个特定的对象来说可能是最终的,这就意味着它不会再改变。 它只能被设置一次,试图重新设置会导致错误被抛出。 这是有用的,有很多原因,也许你想给一个对象的名字,这是不能改变的。

一些示例代码:

 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); } } 

维基百科包含java关键字的完整列表。

静态意味着在类的所有实例共享的内存中只有一个variables副本。 最后的关键字只是意味着值不能改变。 没有final ,任何对象都可以改变variables的值。

我不会在这里给出完整的答案。 我的build议是把重点放在理解他们每个人做什么,然后应该清楚地看到他们的影响是完全不同的,为什么有时他们一起使用。

static是一个类的成员(属性和方法),它必须与实例(非静态)成员相对照。 我build议阅读“ Java教程”中的“理解实例和类成员” 。 我也可以使用static块,但我不会担心它的一个开始。

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