李興華Java 8ノート17:staticキーワード詳細
37892 ワード
1.static定義属性
staticを説明する前に、まずコードを観察します.
class Book{
private String title;
private Double price;
String pub = " ";
public Book(String title,Double price){
this.title = title;
this.price = price;
}
public String getInfo(){
return " :"+this.title+"、 :"+this.price+"、 :"+this.pub;
}
}
public class Hello{
public static void main(String[] args){
Book book1 = new Book("Java",12.2);
Book book2 = new Book("python",132.2);
Book book3 = new Book("C++",52.2);
// static
// ,
book1.pub = " ";
System.out.println(book1.getInfo()); // ...
System.out.println(book2.getInfo()); // ...
System.out.println(book3.getInfo()); // ...
}
}
メモリ解析
メモリにより,各オブジェクトの出版社情報は同じであることが分かったが,この場合,各オブジェクトが独立して同じ属性情報を占有する必要があるのだろうか.私たちがこの方法で1000 Wの図書の情報を保存したとすれば、出版社はみな同じで、同じ属性を独占している.この1000 W本の出版社情報をさらに変更するには、1000 W回の変更が必要です.
以上のように、属性を通常の方法で定義すると、各オブジェクトは独立してそれぞれの属性情報を保存する.この構造式はメンテナンスが不便です.さらに、各オブジェクトに同じプロパティがある場合は、共有する必要があります.共有する方法はstaticキーワードで修飾することです
class Book{
private String title;
private Double price;
static String pub = " ";
public Book(String title,Double price){
this.title = title;
this.price = price;
}
public String getInfo(){
return " :"+this.title+"、 :"+this.price+"、 :"+this.pub;
}
}
public class Hello{
public static void main(String[] args){
Book book1 = new Book("Java",12.2);
Book book2 = new Book("python",132.2);
Book book3 = new Book("C++",52.2);
// static
// ,
book1.pub = " ";
//
System.out.println(book1.getInfo());
System.out.println(book2.getInfo());
System.out.println(book3.getInfo());
}
}
メモリの割り当て
staticキーワードで修飾されたプロパティは、複数のオブジェクトによって同時に指向されるグローバルデータ領域である独立したメモリに格納されます.また、各オブジェクトには属性情報が個別に格納されません.
staticが共通の属性である以上、前のコードでは、1つのオブジェクトで属性を変更するのは適切ではなく、正しい方法はすべてのオブジェクトの共通の代表によって属性を変更することです.この代表はクラスです.簡単に言えば、staticキーワードによって修飾されたプロパティは、クラスによって直接呼び出されます.したがって、pubプロパティを変更するには、次のコードを使用します.変更後、すべてのオブジェクトに有効になります.
Book.pub = " ";
staticと非static修飾のプロパティには最大の違いがあります.static修飾のプロパティは、オブジェクトをインスタンス化する必要がなく、クラスによって直接呼び出されます.では、いつstaticで修飾しますか.いつ使いませんか.
クラスを作成する過程で、あなたが選択した主な修飾子はstaticではなく、95%の場合staticではありません.共有情報を記述するときにstaticを使用すると、集団で修正したり、スペースを節約したりすることができます.
2.static定義方法
static定義メソッドは、インスタンス化されていないときにクラスによって直接呼び出されることもできます.
class Book{
private String title;
private Double price;
private static String pub = " ";
public Book(String title,Double price){
this.title = title;
this.price = price;
}
public String getInfo(){
return " :"+this.title+"、 :"+this.price+"、 :"+this.pub;
}
public static void setPub(String p){
pub = p;
}
}
public class Hello{
public static void main(String[] args){
// static , static
Book.setPub(" ");
Book book1 = new Book("Java",12.2);
Book book2 = new Book("python",132.2);
Book book3 = new Book("C++",52.2);
//
System.out.println(book1.getInfo());
System.out.println(book2.getInfo());
System.out.println(book3.getInfo());
}
}
staticによって修飾されたメソッドと属性は、インスタンス化されたクラスによって制限されず、クラスによって直接呼び出されることがわかります.しかし、このとき特に面倒な問題が発生し、クラスのメソッドは2つのグループになります.1つはstaticメソッドで、1つは非staticです.2つのグループのメソッド間の相互アクセスも制限されます.
class Book{
private String title;
private Double price;
private static String pub = " ";
public Book(String title,Double price){
this.title = title;
this.price = price;
}
// static static
public static String getInfo(){
return " :"+this.title+"、 :"+this.price+"、 :"+this.pub;
}
}
public class Hello{
public static void main(String[] args){
Book.getInfo(); //
}
}
class Book{
private String title;
private Double price;
private static String pub = " ";
public Book(String title,Double price){
this.title = title;
this.price = price;
}
public static String getInfo(){
return " :"+pub;
}
// static static
public String getPub(){
return this.getInfo();
}
}
public class Hello{
public static void main(String[] args){
Book.getInfo(); //
}
}
どうしてこんなことになったの?
主クラスでのメソッドは、staticメソッドを付けて修飾されるのが一般的ですが、付けないとエラーが表示されます.以下のようにします.
public class Hello{
public static void main(String[] args){
fun();//
}
public void fun(){
System.out.println("hello");
}
}
プライマリクラスをインスタンス化してfunメソッドを呼び出すと、エラーは発生しません.
public class Hello{
public static void main(String[] args){
new Hello().fun();//
}
public void fun(){
System.out.println("hello");
}
}
では、いつstaticで修飾するのでしょうか.
class Book{
private boolean flag;
public Book(boolean falg){
this.flag = flag;
}
public void fun(){
if(this.flag){
System.out.println(" ");
}else{
System.out.println(" ");
}
}
}
public class Hello{
public static void main(String[] args){
Book b1 = new Book(true);
Book b2 = new Book(false);
b1.fun();
b2.fun();
}
}
class Book{
public static int sum(int x, int y){
return x + y;
}
}
public class Hello{
public static void main(String[] args){
System.out.println(Book.sum(5,6));
}
}
3.主な方法
メソッドの構成は次のとおりです.
コンパイルファイルを実行するときに、主クラス名の後ろにスペースで区切られたパラメータを付けることができます.パラメータ自体にスペースがある場合は、二重引用符で囲むことができます.
public class Hello{
public static void main(String[] args){
for(int i = 0; i<args.length; i++){
System.out.println(args[i]);
}
}
}
//
java Hello "hello world" hello word
//
hello world
hello
word
3.staticの実用化
3.1クラスインスタンス化対象個数の統計を実現する
オブジェクトをインスタンス化するたびに、x番目のインスタンス化オブジェクトを生成する情報を印刷することが望ましい.
新しいインスタンス化オブジェクトが生成されると、コンストラクションメソッドが呼び出されるので、コンストラクションメソッドでインスタンス化オブジェクトの回数を1回加算することができます.
class Book{
private String title;
private static int num = 0;
public Book(String title){
this.title = title;
this.num = ++this.num;
System.out.println(" "+this.num+" ");
}
}
public class Hello{
public static void main(String[] args){
Book boo1 = new Book("java");
Book boo2 = new Book("java");
Book boo3 = new Book("java");
Book boo4 = new Book("java");
}
}
//
1
2
3
4