具体的には、私はこのコードを試していました:
package hello;
public class Hello {
Clock clock = new Clock();
public static void main(String args[]) {
clock.sayTime();
}
}
しかし、それはエラーを与えました
静的メソッドmainの非静的フィールドにアクセスできません
だから私は宣言を変更しましたclock
これに:
static Clock clock = new Clock();
そしてそれはうまくいった。そのキーワードを宣言の前に置くことはどういう意味ですか?そのオブジェクトに対して何ができるのかという点で、厳密には何をしたり、制限したりしますか。
static
メンバーは特定のインスタンスではなくクラスに属します。
だということだのインスタンスは1つだけstatic
フィールドが存在します[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"クラス
それで、あなたがあなたのコードのどこかで「新しい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();
}
}
main()
ルーチンは自己完結型であるべきです。 - Jason Smain
OPがやったので方法。代わりに、それが他の場所から呼び出されたパブリックメソッドであり、Helloクラスが複数回インスタンス化されている場合は、各Helloインスタンスに対してClockインスタンスを作成できます。clock
静的でした。 - Paul Tomblin
のstatic
キーワードは、何か(フィールド、メソッド、またはネストクラス)がタイプ特定のものではなく実例タイプの。そのため、たとえば、Math.sin(...)
のインスタンスなしでMath
クラス、そして確かにあなたできないのインスタンスを作成しますMath
クラス。
詳しくは、OracleのJavaチュートリアルの関連部分。
ウィー
残念ながらJava許可するインスタンスメンバーのように静的メンバーにアクセスします。
// Bad code!
Thread.currentThread().sleep(5000);
someOtherThread.sleep(5000);
それはそれを作ります見てかのようにsleep
インスタンスメソッドですが、実際には静的メソッドです - それは常に現在のスレッドをスリープ状態にします。呼び出し側のコードでこれを明確にすることをお勧めします。
// Clearer
Thread.sleep(5000);
System.out
型の名前が好きではありません。 - Jon Skeet
のstatic
Javaのキーワードとは、そのクラスのすべてのインスタンス間で変数または関数が共有されることを意味します。タイプ実際の物そのものではありません。
あなたが変数を持っているのであれば:private static int i = 0;
そしてあなたはそれを増やす(i++
1つの例では、変更はすべての例に反映されます。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";
静的とは、クラスに関連付けられたメソッドや変数を使用するためにクラスのインスタンスを作成する必要がないということです。あなたの例では、あなたは呼び出すことができます:
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キーワードはクラスのインスタンスよりもクラスに属します。 変数またはメソッドをクラスにアタッチするために使用できます。
静的キーワードは、以下とともに使用できます。
方法
変数
別のクラス内に入れ子になったクラス
初期化ブロック
以下と一緒に使用することはできません。
クラス(入れ子になっていない)
コンストラクタ
インターフェース
メソッドローカル内部クラス(違いがある場合は入れ子になったクラス)
内部クラスメソッド
インスタンス変数
ローカル変数
例:
次の例を想像してみてください。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
インスタンス変数はオブジェクト作成時にメモリを取得するので、各オブジェクトはインスタンス変数のコピーを持ちます。それが増加しても、他のオブジェクトには反映されません。
今なら私たちはインスタンス変数の数を静的に変更します。その場合、プログラムは異なる出力を生成します。
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として宣言した場合、どのオブジェクトも値がfinalであるため変更できません。そのため、finalおよびstaticとして宣言された変数は、定数と呼ばれることがあります。インターフェースのすべてのフィールドは、デフォルトでは最終的で静的なので、定数と呼ばれます。
画像リソース:ファイナルスタティック
この説明では、これまでクラスローダーの考慮事項を無視しています。厳密に言えば、Java静的フィールドは特定のクラスのすべてのインスタンス間で共有されます。クラスローダー。
フィールドは、クラスまたはクラスのインスタンスに割り当てることができます。デフォルトでは、フィールドはインスタンス変数です。を使ってstatic
フィールドはクラス変数になるので、唯一のものがありますclock
。あなたが一箇所で変更を加えた場合、それはいたるところに表示されます。インスタンス変数は互いに独立して変更されます。
Javaでは、static
キーワードは単に次のことを示すものと見なすことができます。
「特定のインスタンスとは関係なく、または関係なく」
あなたが考えるならstatic
このようにして、それが遭遇するさまざまな文脈におけるその使用法を理解することがより簡単になります。
Astatic
fieldは特定のインスタンスではなくクラスに属するフィールドです。
Astatic
methodはの概念がないメソッドですthis
;それはクラスで定義されており、参照が渡されない限り、そのクラスの特定のインスタンスについては知りません。
Astatic
メンバークラスは、その親クラスのインスタンスについての概念や知識がないネストクラスです(親クラスのインスタンスへの参照が渡されない限り)。
静的は、クロックメンバーをインスタンスメンバーではなくクラスメンバーにします。 staticキーワードがなければ、Helloクラスのインスタンス(clockメンバ変数を持つ)を作成する必要があります。
Hello hello = new Hello();
hello.clock.sayTime();
私は "ヘルパー"クラスの静的メソッド(可能な場合のみ)を好みます。
呼び出し側クラスは、ヘルパークラスの別のメンバ(インスタンス)変数を作成する必要はありません。ヘルパークラスのメソッドを呼び出すだけです。また、コンストラクタが不要になり、メンバ(インスタンス)変数が不要になるため、ヘルパークラスも改善されています。
おそらく他の利点があります。
キーワードstatic
インスタンスではなくクラス自体に属するものとしてフィールドまたはメソッドを示すために使用されます。あなたのコードを使用して、オブジェクトClock
静的であり、のすべてのインスタンスHello
クラスはこれを共有しますClock
データメンバ(フィールド)は共通です。あなたがそれを非静的にすると、それぞれの個々のインスタンスはHello
ユニークなことができますClock
フィールド。
問題は、あなたが追加したということです。メインクラスへのメソッドHello
あなたがコードを実行できるように。ここでの問題はメインmethodは静的なので、その内部の非静的フィールドまたはメソッドを参照することはできません。これを解決するには2つの方法があります。
Hello
それらが内部で参照できるようにクラスstaticメイン方法。これは実際には良いことではありません(あるいはフィールドやメソッドを静的にする間違った理由)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();
}
}
静的メンバーが "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);
}
}
出力:コンパイル時エラー
静的変数静的メソッドでのみアクセスできるので、静的変数を宣言すると、これらの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;
}
}
//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
}
}
あるプロジェクトを実行するとき、最初に静的なもの(変数、メソッド、ブロックなど)をロードします。
このプロジェクトを実行すると、最初にメインメソッドがロードされます。それはだからstatic method
。それからそれはオブジェクトに見えます"a" object
.Butオブジェクトはまだ定義されていません。その非静的だから。その後、このエラーのようになります。