具体的には、私はこのコードを試していました:
package hello;
public class Hello {
Clock clock = new Clock();
public static void main(String args[]) {
clock.sayTime();
}
}
しかし、それはエラーを与えました
Staticメソッドmainの非staticフィールドにアクセスできません
だから私はclock
の宣言をこれに変更しました:
static Clock clock = new Clock();
そしてそれはうまくいった。そのキーワードを宣言の前に置くことはどういう意味ですか?そのオブジェクトに対して何ができるのかという点で、それは正確に何をし、そして/または制限するでしょうか。
static
メンバーは、特定のインスタンスではなくクラスに属しています。
だということだ static
フィールドのインスタンスは1つだけ存在します[1] たとえあなたがクラスのインスタンスを何百万も作成したとしても、作成しなくても。すべてのインスタンスで共有されます。
static
メソッドも特定のインスタンスに属していないため、インスタンスメンバーを参照できません。与えられた例では、main
はHello
クラスのどのインスタンス(したがってClock
クラスのどのインスタンス)を参照すべきかを知りません。 static
メンバーは、static
メンバーのみを参照できます。インスタンスメンバーはもちろんstatic
メンバーにアクセスできます。
サイドノート: もちろん、static
メンバーはインスタンスメンバーにアクセスできます。 オブジェクト参照を通じて。
例:
public class Example {
private static boolean staticField;
private boolean instanceField;
public static void main(String[] args) {
// a static method can access static fields
staticField = true;
// a static method can access instance fields through an object reference
Example instance = new Example();
instance.instanceField = true;
}
[1]:実行時の特性に応じて、ClassLoader、AppDomain、またはスレッドごとに1つになりますが、それは重要なことです。
これは、Helloには "clock"のインスタンスが1つだけで、 "Hello"クラスのインスタンスごとに1つだけではないことを意味します。つまり、すべてのインスタンス間で共通の "clock"参照が1つになります。 "Hello"クラス.
それで、あなたがあなたのコードのどこかで "new Hello"をやろうとしたら:A-最初のシナリオでは( "static"を使わずに)、 "new Hello"が呼ばれるたびに新しい時計を作ります。 B - 2番目のシナリオ(変更後、 "static"を使用)では、すべての "new Hello"インスタンスは、最初に作成された最初の同じ "clock"参照を共有して使用します。
あなたがmainの外側のどこかで "clock"を必要としない限り、これは同様にうまくいくでしょう:
package hello;
public class Hello
{
public static void main(String args[])
{
Clock clock=new Clock();
clock.sayTime();
}
}
static
キーワードは、特定のinstanceではなく、何か(フィールド、メソッド、またはネストされたクラス)がtypeに関連していることを意味します。たとえば、Math
クラスのインスタンスなしでMath.sin(...)
を呼び出すと、実際にca n'tがMath
クラスのインスタンスを作成します。
詳細については、 OracleのJavaチュートリアルの関連ビット を参照してください。
サイドノート
Java残念ながらallowsインスタンスメンバーであるかのように静的メンバーにアクセスできます。
// Bad code!
Thread.currentThread().sleep(5000);
someOtherThread.sleep(5000);
これにより、lookはsleep
がインスタンスメソッドであるかのようになりますが、実際には静的メソッドです。alwaysは、現在のスレッドをスリープ状態にします。呼び出し元のコードでこれを明確にすることをお勧めします。
// Clearer
Thread.sleep(5000);
Javaのstatic
キーワードは、実際のオブジェクト自体ではなく、 type に属するため、変数または関数がそのクラスのすべてのインスタンス間で共有されることを意味します。
したがって、変数private static int i = 0;
があり、それを1つのインスタンスでインクリメント(i++
)すると、その変更はすべてのインスタンスに反映されます。 i
はすべてのインスタンスで1になります。
オブジェクトをインスタンス化せずに静的メソッドを使用できます。
静的メンバーの基本的な使い方.
public class Hello
{
// value / method
public static String staticValue;
public String nonStaticValue;
}
class A
{
Hello hello = new Hello();
hello.staticValue = "abc";
hello.nonStaticValue = "xyz";
}
class B
{
Hello hello2 = new Hello(); // here staticValue = "abc"
hello2.staticValue; // will have value of "abc"
hello2.nonStaticValue; // will have value of null
}
これにより、クラスインスタンスHelloを他のクラスに送信しなくても、すべてのクラスメンバーで値を共有できます。そして静的であれば、クラスインスタンスを作成する必要はありません。
Hello hello = new Hello();
hello.staticValue = "abc";
クラス名で静的な値やメソッドを呼び出すことができます。
Hello.staticValue = "abc";
Javaでは静的:
静的は非アクセス修飾子です。 staticキーワードはクラスのインスタンスよりもクラスに属します。変数またはメソッドをクラスにアタッチするために使用できます。
静的キーワードは:とともに使用できます
方法
変数
別のクラス内に入れ子になったクラス
初期化ブロック
:は使用できません
クラス(入れ子になっていない)
コンストラクタ
インターフェース
メソッドローカル内部クラス(違いがある場合は入れ子になったクラス)
内部クラスメソッド
インスタンス変数
ローカル変数
例:
次の例で想像してみてください。コンストラクター内で増分されるcountという名前のインスタンス変数
package pkg;
class StaticExample {
int count = 0;// will get memory when instance is created
StaticExample() {
count++;
System.out.println(count);
}
public static void main(String args[]) {
StaticExample c1 = new StaticExample();
StaticExample c2 = new StaticExample();
StaticExample c3 = new StaticExample();
}
}
出力:
1 1 1
インスタンス変数はオブジェクト作成時にメモリを取得するため、各オブジェクトはインスタンス変数のコピーを持ちます。インクリメントされても他のオブジェクトには反映されません。
インスタンス変数の数を静的に変更 oneの場合、プログラムは異なる出力を生成します。
package pkg;
class StaticExample {
static int count = 0;// will get memory when instance is created
StaticExample() {
count++;
System.out.println(count);
}
public static void main(String args[]) {
StaticExample c1 = new StaticExample();
StaticExample c2 = new StaticExample();
StaticExample c3 = new StaticExample();
}
}
出力:
1 2 3
この場合、静的変数は一度だけメモリを取得します。オブジェクトが静的変数の値を変更しても、その値は保持されます。
Final with Static:
finalおよびstaticとして宣言されているグローバル変数は、実行全体にわたって変更されません。なぜなら、静的メンバーはクラスメモリに格納され、実行全体で一度だけロードされるからです。それらはクラスのすべてのオブジェクトに共通です。静的変数をfinalとして宣言した場合、どのオブジェクトも値がfinalであるため変更できません。そのため、finalおよびstaticとして宣言された変数は、定数と呼ばれることがあります。インターフェースのすべてのフィールドは、デフォルトでは最終フィールドで静的なので、定数と呼ばれます。
Picture Resource: ファイナルスタティック
静的とは、クラスに関連付けられたメソッドや変数を使用するためにクラスのインスタンスを作成する必要がないということです。あなたの例では、あなたは呼び出すことができます:
Hello.main(new String[]()) //main(...) is declared as a static function in the Hello class
次の代わりに直接
Hello h = new Hello();
h.main(new String[]()); //main(...) is a non-static function linked with the "h" variable
静的メソッド(クラスに属する)の内部からは、静的ではないメンバーにはアクセスできません。メンバーの値はクラスのインスタンス化に依存するためです。インスタンスメンバである非静的Clockオブジェクトは、Helloクラスのインスタンスごとに異なる値/参照を持つことになるため、クラスの静的部分からアクセスすることはできません。
この説明では、これまでクラスローダーの考慮事項を無視しています。厳密に言うと、Javaの静的フィールドは特定の クラスローダー のクラスのすべてのインスタンス間で共有されます。
フィールドは、クラスまたはクラスのインスタンスに割り当てることができます。デフォルトでは、フィールドはインスタンス変数です。 static
を使用することでフィールドはクラス変数になります。したがってclock
は1つだけです。あなたが一箇所で変更を加えた場合、それはどこにでも表示されます。インスタンス変数は互いに独立して変更されます。
Javaでは、static
キーワードは単に次のことを示すと見なすことができます。
「特定のインスタンスとは関係なく、または関係なく」
このようにstatic
を考えると、それが遭遇するさまざまな文脈でその使用法を理解するのがより簡単になります。
static
フィールドは、特定のインスタンスではなくクラスに属するフィールドです。
static
メソッドはthis
の概念がないメソッドです。それはクラスで定義されており、参照が渡されない限りそのクラスの特定のインスタンスについては知りません。
static
メンバクラスは、その親クラスのインスタンスについての概念や知識がないネストクラスです(親クラスのインスタンスへの参照が渡されない限り)。
キーワードstatic
は、インスタンスではなくクラス自体に属するものとしてフィールドまたはメソッドを示すために使用されます。コードを使用して、オブジェクトClock
が静的である場合、Hello
クラスのすべてのインスタンスはこのClock
データメンバ(field)を共有します。静的にしない場合、Hello
の個々のインスタンスはそれぞれ固有のClock
フィールドを持つことができます。
問題は、コードを実行できるように、クラスHello
に main メソッドを追加したことです。ここでの問題は、 main メソッドが静的であり、それ自体の内部で非静的フィールドやメソッドを参照できないことです。これを解決するには2つの方法があります。
Hello
クラスのすべてのフィールドとメソッドを静的にします。これは実際には良いことではありません(あるいはフィールドやメソッドを静的にする間違った理由)Hello
クラスのインスタンスを作成し、そもそも意図した方法でそのすべてのフィールドとメソッドにアクセスします。あなたのために、これはあなたのコードに次のような変更があることを意味します。
package hello;
public class Hello {
private Clock clock = new Clock();
public Clock getClock() {
return clock;
}
public static void main(String args[]) {
Hello hello = new Hello();
hello.getClock().sayTime();
}
}
私は "ヘルパー"クラスの静的メソッド(可能な場合のみ)を好みます。
呼び出し側クラスは、ヘルパークラスの別のメンバー(インスタンス)変数を作成する必要はありません。ヘルパークラスのメソッドを呼び出すだけです。また、コンストラクタが不要になり、メンバ(インスタンス)変数が不要になるため、ヘルパークラスも改善されています。
おそらく他の利点があります。
静的は、クロックメンバーをインスタンスメンバーではなくクラスメンバーにします。 staticキーワードがなければ、Helloクラスのインスタンス(clockメンバ変数を持つ)を作成する必要があります。
Hello hello = new Hello();
hello.clock.sayTime();
静的メソッドは、それらが定義されているクラスのインスタンス変数を使用しません。違いについての非常に良い説明は このページ にあります。
静的メンバーが "this"ポインタを持たないことも考えられます。それらはすべてのインスタンスで共有されています。
静的概念を理解する
public class StaticPractise1 {
public static void main(String[] args) {
StaticPractise2 staticPractise2 = new StaticPractise2();
staticPractise2.printUddhav(); //true
StaticPractise2.printUddhav(); /* false, because printUddhav() is although inside StaticPractise2, but it is where exactly depends on PC program counter on runtime. */
StaticPractise2.printUddhavsStatic1(); //true
staticPractise2.printUddhavsStatic1(); /*false, because, when staticPractise2 is blueprinted, it tracks everything other than static things and it organizes in its own heap. So, class static methods, object can't reference */
}
}
セカンドクラス
public class StaticPractise2 {
public static void printUddhavsStatic1() {
System.out.println("Uddhav");
}
public void printUddhav() {
System.out.println("Uddhav");
}
}
main()
は、2つの基本的な制限がある静的メソッドです。
this()
とsuper()
は静的コンテキストでは使用できません。
class A {
int a = 40; //non static
public static void main(String args[]) {
System.out.println(a);
}
}
出力:コンパイル時エラー
//Here is an example
public class StaticClass
{
static int version;
public void printVersion() {
System.out.println(version);
}
}
public class MainClass
{
public static void main(String args[]) {
StaticClass staticVar1 = new StaticClass();
staticVar1.version = 10;
staticVar1.printVersion() // Output 10
StaticClass staticVar2 = new StaticClass();
staticVar2.printVersion() // Output 10
staticVar2.version = 20;
staticVar2.printVersion() // Output 20
staticVar1.printVersion() // Output 20
}
}
静的変数静的メソッドでのみアクセスできるので、静的変数を宣言すると、これらのgetterメソッドとsetterメソッドは静的メソッドになります。
静的メソッドはクラス名を使ってアクセスできるクラスレベルです
以下は、静的変数の取得メソッドと設定メソッドの例です。
public class Static
{
private static String owner;
private static int rent;
private String car;
public String getCar() {
return car;
}
public void setCar(String car) {
this.car = car;
}
public static int getRent() {
return rent;
}
public static void setRent(int rent) {
Static.rent = rent;
}
public static String getOwner() {
return owner;
}
public static void setOwner(String owner) {
Static.owner = owner;
}
}
あるプロジェクトを実行するとき、最初に静的なもの(変数、メソッド、ブロックなど)をロードします。
このプロジェクトを実行すると、最初にメインメソッドがロードされます。そのstatic method
ので。それからオブジェクト"a" object
.Butオブジェクトはまだ定義されていないように見えます。その非静的だから。その後、このエラーのようになります。