1. 静的メソッド
静的メソッドは何にも依存しないため、一般に静的メソッドと呼ばれます。 object アクセスできるので、静的メソッドの場合は、オブジェクトにアタッチされていないため、this はありません オブジェクトがないため、this はありません。また、この機能により、クラスの非静的メンバー変数および非静的メンバー メソッドに静的メソッドでアクセスすることはできません。これは、非静的メンバー メソッド/変数は呼び出す前に特定のオブジェクトに依存する必要があるためです。
ただし、非静的メンバー メソッドと非静的メンバー変数には静的メソッドではアクセスできませんが、静的メンバー メソッド/変数には非静的メンバー メソッドでアクセスできることに注意してください。簡単な例:
上記のコードでは、print2 メソッドはオブジェクトとは独立して存在するため、クラス名を使用して直接呼び出すことができます。非静的メソッド/変数が静的メソッドでアクセスできる場合、メイン メソッドに次のステートメントがある場合:
MyObject.print2();
現時点ではオブジェクトがありません。str2 はまったく存在しません。 、したがって、競合が発生します。メソッドについても同様で、print1メソッドでは非静的メンバ変数にアクセスするかどうか予測できないため、静的メンバメソッド内での非静的メンバ変数へのアクセスも禁止されています。
非静的メンバー メソッドの場合、静的メンバー メソッド/変数へのアクセスに制限はありません。
したがって、オブジェクトを作成せずにメソッドを呼び出したい場合は、このメソッドを static に設定できます。最も一般的な静的メソッドは main メソッドですが、main メソッドが静的である必要がある理由については、これで明らかになりました。プログラムは main メソッドの実行時にオブジェクトを作成しないため、クラス名を介してのみアクセスできます。
## を参照してください。
静的変数は静的変数とも呼ばれます。静的変数と非静的変数の違いは次のとおりです: 静的変数はすべてのオブジェクトによって共有され、メモリ内には 1 つだけあり、コピーは [メソッド領域に保存] され、クラスが初めてロードされた場合にのみ初期化されます (final ありとなしの静的変数の初期化場所は異なります)。非静的変数はオブジェクトによって所有され、オブジェクトの作成時に初期化されます。複数のコピーがあり、各オブジェクトが所有するコピーは相互に影響しません。
静的メンバー変数の初期化順序は、定義された順序で初期化されます。
静的キーワードは、プログラムのパフォーマンスを最適化するために静的コード ブロックを形成する際にも重要な役割を果たします。静的ブロックはクラス内のどこにでも配置でき、クラス内に複数の静的ブロックが存在する可能性があります。クラスが初めてロードされるとき、各静的ブロックは静的ブロックの順序で実行され、1 回だけ実行されます [クラス ロードの原則に従って、各クラスは親委任ロードを使用して 1 回ロードされます]。
初期化シーケンスの静的コード ブロック>構築コード ブロック>コンストラクター関数
public class Client { {//构造代码块 System.out.println("执行构造代码块"); } }
静的ブロックを使用してプログラムのパフォーマンスを最適化できる理由は、その特性によるものです。クラスが次の場合にのみロードされます。ロードされた場合は 1 回実行されます。例を見てみましょう:
class Person{ private Date birthDate; public Person(Date birthDate) { this.birthDate = birthDate; } boolean isBornBoomer() { Date startDate = Date.valueOf("1946"); Date endDate = Date.valueOf("1964"); return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0; } }
isBornBoomer は、その人が 1946 年から 1964 年の間に生まれたかどうかを判断するために使用されます。isBornBoomer が呼び出されるたびに、startDate とbirthDate の 2 つのオブジェクトが生成され、結果として無駄が生じます。スペース。これに変更すると、効率が良くなります。実際、静的コード ブロックを一度メモリにロードするメカニズムが使用されています:
class Person{ private Date birthDate; private static Date startDate,endDate; static{ startDate = Date.valueOf("1946"); endDate = Date.valueOf("1964"); } public Person(Date birthDate) { this.birthDate = birthDate; } boolean isBornBoomer() { return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0; } }
したがって、多くの場合、必要な初期化操作は、一度実行されたものは静的コード ブロックに配置されます。
4. 静的内部クラスここでは静的内部クラスを個別に記述するのではなく、通常の内部クラスと比較することで静的内部クラスの理解を深めます。
##なぜ内部クラスを使用するのでしょうか? 1. 内部クラスは通常、その外部クラスによってのみ使用されます; [外部クラスによって使用される良い例は、ハッシュマップ コレクションに内部クラス Entry があり、使用するためにハッシュマップ ストレージに変換されることです。 ] 2. 内部クラスは外部クラスへの何らかのウィンドウを提供します。内部クラスは外部クラスへの参照を持っているため、内部クラスは外部クラスのプロパティに直接アクセスできます。3. これが最も魅力的な理由でもありますが、外部クラスがインターフェイスを継承しているかどうかに関係なく、各内部クラスは独立してインターフェイスを継承できます。したがって、内部クラスにより、多重継承の解決策がより完全になります。
クラス内に定義されたクラスを内部クラスと呼び、内部クラスを含むクラスを外部クラスと呼びます。内部クラスは、public、protected、private などのアクセス制限を宣言したり、他の内部クラスや外部クラスが継承および拡張するために抽象として宣言したり、静的または最終的に宣言したり、特定のインターフェイスを実装したりできます。
外部类按常规的类访问方式(以对象的方式)使用内部 类,唯一的差别是外部类可以访问内部类的所有方法与属性,包括私有方法与属性,外部类访问内部类,需要创建对象访问;有一点需要注意,内部类不能访问外部类所在的局部变量,只能访问final修饰的局部变量。
在方法内定义内部类时,如果内部类调用了方法中的变量,那么该变量必须申明为final类型,百思不得其解,后来想到应该是生命周期的原因,因为方法内定义的变量是局部变量,离开该方法,变量就失去了作用,也就会自动被消除,而内部类却不会离开它所在方法就失去作用,它有更广的生命周期。
(1)创建实例
OutClass.InnerClass obj = outClassInstance.new InnerClass(); //注意是外部类实例.new,内部类 AAA.StaticInner in = new AAA.StaticInner();//注意是外部类本身,静态内部类
(2)内部类中的this
内部类中的this与其他类一样是指的本身。创建内部类对象时,它会与创造它的外围对象有了某种联系,于是能访问外围类的所有成员,不需任何特殊条件,可理解为内部类链接到外部类。 用外部类创建内部类对象时,此内部类对象会秘密的捕获一个指向外部类的引用,于是,可以通过这个引用来访问外围类的成员。
(3)外部类访问内部类
内部类类似外部类的属性,因此访问内部类对象时总是需要一个创建好的外部类对象。外部类对象通过‘外部类名.this.xxx’的形式访问内部类的属性与方法。如:
System.out.println("Print in inner Outer.index=" + pouter.this.index); System.out.println("Print in inner Inner.index=" + this.index);
(4)内部类向上转型
内部类也可以和普通类一样拥有向上转型的特性。将内部类向上转型为基类型,尤其是接口时,内部类就有了用武之地。如果内部类是private的,只可以被它的外部类问,从而完全隐藏实现的细节。
(5)方法内的类
方法内创建的类(注意方法中也能定义类),不能加访问修饰符。另外,方法内部的类也不是在调用方法时才会创建的,它们一样也被事先编译了。
(6)静态内部类
定义静态内部类:在定义内部类的时候,可以在其前面加上一个权限修饰符static。此时这个内部类就变为了静态内部类。
通常称为嵌套类,当内部类是static时,意味着:
[1]要创建嵌套类的对象,并不需要其外围类的对象;
[2]不能从嵌套类的对象中访问非静态的外围类对象(不能够从静态内部类的对象中访问外部类的非静态成员);
嵌 套类与普通的内部类还有一个区别:普通内部类的字段与方法,只能放在类的外部层次上,所以普通的内部类不能有static数据和static字段, 也不能包含嵌套类。但是在嵌套类里可以包含所有这些东西。也就是说,在非静态内部类中不可以声明静态成员,只有将某个内部类修饰为静态类,然后才能够在这 个类中定义静态的成员变量与成员方法。
另外,在创建静态内部类时不需要将静态内部类的实例绑定在外部类的实例上。普通非静态内部类的 对象是依附在外部类对象之中的,要在一个外部类中定义一个静态的内部类,不需要利用关键字new来创建内部类的实例。静态类和方法只属于类本身,并不属于 该类的对象,更不属于其他外部类的对象。
(7)内部类标识符
每个类会产生一个.class文件,文件名即为类名。同样,内部类也会产生这么一个.class文件,但是它的名称却不是内部类的类名,而是有着严格的限制:外围类的名字,加上$,再加上内部类名字。
代码具体:
public class OutClassTest { static int a; int b; public static void test() { System.out.println("outer class static function"); } public static void main(String[] args) { // new一个外部类 OutClassTest oc1 = new OutClassTest(); // 通过外部类的对象new一个非静态的内部类 OutClassTest.InnerClass no_static_inner = oc1.new InnerClass(); // 调用非静态内部类的方法 System.out.println(no_static_inner.getKey()); // 调用静态内部类的静态变量 System.out.println(OutClassTest.InnerStaticClass.static_value); // 不依赖于外部类实例,直接实例化内部静态类 OutClassTest.InnerStaticClass inner = new OutClassTest.InnerStaticClass(); // 调用静态内部类的非静态方法 System.out.println(inner.getValue()); // 调用内部静态类的静态方法 System.out.println(OutClassTest.InnerStaticClass.getMessage()); } private class InnerClass { // 只有在静态内部类中才能够声明或定义静态成员 // private static String tt = "0"; private int flag = 0; public InnerClass() { // 三.非静态内部类的非静态成员可以访问外部类的非静态变量和静态变量 System.out.println("InnerClass create a:" + a); System.out.println("InnerClass create b:" + b); System.out.println("InnerClass create flag:" + flag); // System.out.println("InnerClass call outer static function"); // 调用外部类的静态方法 test(); } public String getKey() { return "no-static-inner"; } } private static class InnerStaticClass { // 静态内部类可以有静态成员,而非静态内部类则不能有静态成员。 private static String static_value = "0"; private int flag = 0; public InnerStaticClass() { System.out.println("InnerClass create a:" + a); // 静态内部类不能够访问外部类的非静态成员 // System.out.println("InnerClass create b:" + b); System.out.println("InnerStaticClass flag is " + flag); System.out.println("InnerStaticClass tt is " + static_value); } public int getValue() { // 静态内部类访问外部类的静态方法 test(); return 1; } public static String getMessage() { return "static-inner"; } } public OutClassTest() { // new一个非静态的内部类 InnerClass ic = new InnerClass(); System.out.println("OuterClass create"); } }
有就是类名ClassName后面多了个.* ,意思是导入这个类里的静态方法。当然,也可以只导入某个静态方法,只要把 .* 换成静态方法名就行了。然后在这个类中,就可以直接用方法名调用静态方法,而不必用ClassName.方法名 的方式来调用。
好处:这种方法的好处就是可以简化一些操作,例如打印操作System.out.println(…);就可以将其写入一个静态方法print(…),在使用时直接print(…)就可以了。但是这种方法建议在有很多重复调用的时候使用,如果仅有一到两次调用,不如直接写来的方便
example:
在Java 5中,import语句得到了增强,以便提供甚至更加强大的减少击键次数功能,虽然一些人争议说这是以可读性为代价的。这种新的特性成为静态导入。当你想使用static成员时,可以使用静态导入(在API中的类和你自己的类上,都可以使用该特性)。下面是静态导入前后的代码实例:
在静态导入之前:
public class TestStatic { public static void main(String[] args) { System.out.println(Integer.MAX_VALUE); System.out.println(Integer.toHexString(42)); } }
在静态导入之后:
import static java.lang.System.out; import static java.lang.Integer.*; public class TestStaticImport { public static void main(String[] args) { out.println(MAX_VALUE); out.println(toHexString(42)); } }
让我们看一下使用静态导入特性的代码中将发生什么:
1. この機能は「静的インポート」と呼ばれることが多いですが、構文は import static の後に、インポートする静的メンバーの完全修飾名またはワイルドカード文字を続ける必要があります。この例では、System クラスの out オブジェクトに対して静的インポートを作成します。
2. この例では、java.lang.Integer クラスのいくつかの静的メンバーを使用することができます。この静的インポート ステートメントでは、ワイルドカードを使用して、「このクラスのすべての静的メンバーに対して静的インポートを実行したい」と指定しています。
3. ここで、ようやく静的インポート機能の利点がわかりました。 System.out.println に System と入力する必要はありません。とても良い!また、Integer.MAX_VALUE に Integer を入力する必要もありません。したがって、このコード行では、静的メソッドと定数のショートカットを使用できます。
4. 最後に、今回は Integer クラスのメソッドに対して、さらにショートカット操作を実行します。
この機能について少し皮肉を言われてきましたが、私たちだけではありません。いくつかのキーストロークを節約することでコードが読みにくくなるとは考えていませんが、多くの開発者が言語にコードを追加するよう求めています。
静的インポートを使用するためのいくつかの原則を以下に示します。
静的インポートではなく、静的インポートと言う必要があります。
曖昧な名前の静的メンバーに注意してください。たとえば、Integer クラスと Long クラスで静的インポートを実行する場合、MAX_VALUE を参照するとコンパイラ エラーが発生します。これは、Integer と Long の両方に MAX_VALUE 定数があり、Java はどの MAX_VALUE を参照しているのかがわからないためです。
静的インポートは、静的オブジェクト参照、定数 (静的または最終的なものであることに注意してください)、および静的メソッドに対して実行できます。
多くの Java トレーニング ビデオ はすべて PHP 中国語 Web サイトにあります。オンラインで学習することを歓迎します。
以上がJavaの静的とは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。