StaticとFinalの違いは?


174

私はいつもの間で混乱しているstaticfinal、キーワードでのjava

それらはどう違いますか ?

回答:


238

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インスタンス変数は、それが宣言されているクラスのすべてのコンストラクターの最後に確実に割り当てる必要があります。同様に、空白のfinal static変数は、それが宣言されているクラスのstatic初期化子で確実に割り当てる必要があります。そうしないと、どちらの場合でもコンパイル時エラーが発生します。

注:変数が参照の場合、これは変数を再バインドして別のオブジェクトを参照することができないことを意味します。しかし、それが参照するオブジェクトは、もともと変更可能であったとしても、変更可能です。

匿名の内部クラスがメソッドの本体内で定義されている場合、finalそのメソッドのスコープ内で宣言されたすべての変数は内部クラス内からアクセスできます。いったん割り当てられると、最終的な変数の値は変更できません。


5
(私はあなたに反対票を投じませんでした)さらに説明:「静的メソッドは静的データのみにアクセスできます。非静的データ(インスタンス変数)にはアクセスできません」-クラスのインスタンスを作成/作成しない限り。「静的メソッドは他の静的メソッドのみを呼び出すことができ、そこから非静的メソッドを呼び出すことはできません。」-クラスのインスタンスを持っている/作成しない限り。
xagyg

1
静的メソッドの構文の説明で間違って言及したと思います。それは可能性Class.methodName()
Mdhar9e

静的クラスを持つこともできます。答えを修正してください。おかげで:)
マドゥスダン

Java 8以降、匿名クラス(およびラムダ)は最終的な変数に効果的にアクセスでき、最終的なキーワードの制限はありません。
akhil_mittal 2017

38

staticはインスタンスではなくクラスに属していることを意味します。これは、特定のClassのすべてのインスタンス間で共有される変数/メソッドのコピーが1つしかないことを意味します。

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は完全に無関係であり、一度だけの初期化を定義する方法です。変数を定義するときに初期化するか、コンストラクタ内で初期化できます。

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

これを、インスタンスごとのコンストラクタの前に呼び出されるインスタンス初期化子ブロックと混同しないでください。


あなたから提供された入力に従うと、すべての混乱のおかげで解決することができます...final is entirely unrelated, it is a way of defining a once only initialization. You can either initialize when defining the variable or within the constructor, nowhere else.
prashant thakre 2014

2
物事があるべきようにシンプルで明確。受け入れられた答えはちょうど……冗長です。

22

2つは本当に似ていません。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。もう1つの違いは、すべての変数をfinal静的に宣言できるわけではないのに、任意の変数を宣言できることです。

また、クラスを宣言finalして、拡張できないことを示すこともできます。

final class C {}

class B extends C {}  // error!

同様に、メソッドをfinalと宣言して、拡張クラスによってオーバーライドできないことを示すことができます

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

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

入力いただきありがとうございます。コードはエラーを出します:クラスC {public static int n = 42; これは、フィールドが非静的型で静的を宣言できないことを示しています。Cnを宣言または実行できないのはなぜですか?
TechnoCorner

@TechnoCornerは、最上位クラス(publicファイルを定義する可能性のあるクラス)またはstatic内部クラスのみがstatic変数を定義できます。他の内部クラスは外部クラスのインスタンスであり、静的変数を持つことはできません。
zapl

17

最後の -

1) " final "キーワードを変数に適用すると、その変数の値は一定のままです。(または)変数finalとして宣言したら、その変数の値は変更できません。

2)プログラムの存続期間中に数値が変化しない場合に役立ちます

静的-

1)変数に「静的」キーワードを適用すると、それはクラスに属していることを意味します。 2)「静的」キーワードをメソッド適用すると、クラスのインスタンスを作成せずにメソッドにアクセスできることを意味します


12

static クラスのすべてのインスタンスで共有されるメモリ内の変数のコピーが1つしかないことを意味します。

finalキーワードだけで値が変更されないことを意味します。なしではfinal、どのオブジェクトでも変数の値を変更できます。


3

staticとfinalにはいくつかの大きな違いがあります。

静的変数またはクラスは、常に(かなり多くの)どこからでも利用できます。Finalは、変数を変更できないことを意味する単なるキーワードです。だから持っていた場合:

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

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

プログラムは、「最初の」整数を変更しようとするまで実行され、エラーが発生します。このクラスの外では、クラスをインスタンス化した場合にのみ「最初の」変数にアクセスできます。これは、常に使用可能な「秒」とは対照的です。


3

スピーカーのようなオブジェクトを考えてください。Speakerがクラスの場合、ボリューム、高音、低音、色などのさまざまな変数が含まれます。これらのフィールドはすべてSpeakerクラスを定義するときに定義します。たとえば、静的修飾子を使用してカラーフィールドを宣言した場合、これは、クラスがインスタンス化された回数に関係なく、この変数のコピーが1つだけ存在することをコンパイラに通知することを意味します。

宣言

static final String color = "Black"; 

このクラスがインスタンス化されるときは常に、変更されない限り、カラーフィールドの値は必ず「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.
}}

このコードをエミュレータに直接コピーして貼り付けてみてください。


2

簡単な違い、

Final:変数の値がFinalであり、どこにも変化しないことを意味します。最終的なx = 5と言えば、xは変更できないことを意味し、その値はすべての人にとって最終的なものです。

静的:は、オブジェクトが1つしかないことを意味します。x = 5で、メモリ内にx = 5があり、クラス内に存在するとします。クラスのオブジェクトまたはインスタンスを作成する場合、つまり、そのクラスとその変数およびメソッドを表す特定のボックスがあります。そのクラスの別のオブジェクトまたはインスタンスを作成する場合、メモリ内の内部に異なるxを持つ同じクラスの2つのボックスがあることを意味します。両方のxを異なる位置で呼び出してそれらの値を変更すると、それらの値は異なります。ボックス1にはx = 5のxがあり、ボックス2にはx = 6がありますが、xを静的にすると、再度作成できないことを意味します。クラスのオブジェクトを作成できますが、そのオブジェクトには異なるxがありません。xが静的である場合、ボックス1とボックス2はどちらも同じxを持ち、値は5です。はい、最終的なものではないため、静的な値をどこでも変更できます。したがって、ボックス1にxがあり、その値をx = 5に変更し、その後、box2である別のボックスを作成し、box2 xの値をx = 6に変更するとします。Xは静的なので、両方のボックスは同じxになります。また、box2は5から6の値を上書きするため、両方のボックスでboxの値は6になります。

finalとstaticはまったく異なります。finalであるfinalは変更できません。staticです。1つのままですが、変更できます。

「これは例です。静的変数は常にそのクラス名で呼び出されることに注意してください。それらはそのクラスのすべてのオブジェクトに対して1つだけなので、クラスAはx = 5なので、Ax = 6で呼び出して変更できます。 」


1

静的は、クラスの任意のオブジェクトが呼び出すことができるものであり、本質的にオブジェクト型に属しています。

変数はクラス全体の最終的なものになる可能性があり、それは単に変更できなくなったことを意味します。設定できるのは1回だけです。もう一度設定しようとすると、エラーがスローされます。これは、変更できない定数を宣言したいなど、さまざまな理由で役立ちます。

いくつかのサンプルコード:

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キーワードの完全なリストが含まれています。


特定のオブジェクトとはどういう意味ですか?説明してください。
TechnoCorner

0

ここでは完全な答えを出そうとはしません。私の推奨は、それぞれが何をしているかを理解することに集中することです。それから、それらの効果が完全に異なり、なぜそれらが一緒に使用されるのかを明らかにする必要があります。

staticクラス(属性とメソッド)のメンバー用であり、インスタンス(非静的)メンバーとは対照的に理解する必要があります。Javaチュートリアルの「インスタンスとクラスメンバーについて」を読むことをお勧めします。staticブロックで使用することもできますが、最初は心配する必要はありません。

final変数、メソッド、クラス、またはその他のケースに適用されるかどうかによって、意味が異なります。ここで私はウィキペディアの説明のほうが好きです。


-1

静的変数の値は変更できますが、変数の1つのコピーはアプリケーションを通過しますが、最終変数の値は一度初期化でき、アプリケーション全体で変更することはできません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.