国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Home Java Javagetting Started Deep understanding of the static keyword

Deep understanding of the static keyword

Nov 27, 2019 pm 04:15 PM
java static

Deep understanding of the static keyword

Before I start talking about static, I want you to see an interesting piece of code:

public class Test {
     
    static{
        System.out.println("test static 1");
    }
  
    static{
        System.out.println("test static 2");
    }
    
    public static void main(String[] args) {
         
    }
}

After reading the program, Xiaobai Tongxiao said: What is this? There is nothing in the main method, so what can it run? Blogger, you are a star...

運(yùn)行結(jié)果:
test static 1
test static 2

小白children's shoes: That what...that what...I said something, blogger, I didn't say anything...

In fact, those who understand the above code will naturally understand it, and those who do not understand will naturally not understand it, because the above code involves JVM class loading! Of course, it is not within the scope of this blog article. If you are interested in understanding the above program, this article may be helpful to you

1. The main significance of static existence

The main meaning of static is to create domain variables or methods that are independent of specific objects. So that even if the object is not created, you can still use properties and call methods!

The static keyword also plays a key role in being used to form static code blocks to optimize program performance. A static block can be placed anywhere in a class, and there can be multiple static blocks in a class. When a class is loaded for the first time, each static block will be executed in the order of the static blocks, and will only be executed once.

Why the static block can be used to optimize program performance is because of its characteristics: it will only be executed once when the class is loaded. Therefore, many initialization operations that only need to be performed once are performed in static code blocks.

[Recommended learning: java video tutorial]

2. The uniqueness of static

1. Variables or methods modified by static are independent of any object of the class. That is to say, these variables and methods do not belong to any instance object, but are shared by instance objects of the class.

How do you understand the sentence "shared by instance objects of a class"? That is to say, a static member of a class belongs to everyone [Everyone refers to multiple object instances of this class. We all know that a class can create multiple instances! ], shared by all class objects, unlike member variables which are personal [self refers to a single instance object of this class]... I think I have made it very simple, do you understand?

2. When the class is loaded for the first time, the part modified by static will be loaded, and it will only be loaded and initialized when the class is used for the first time. Note that this is the first time the class is loaded. It must be initialized once used, and can be assigned again as needed later.

3. The static variable value is allocated space when the class is loaded and will not be reallocated when the class object is created later. If you assign a value, you can assign it arbitrarily!

4. Variables or methods modified by static take precedence over objects, which means that after a class is loaded, it can be accessed even if no object is created.

3. Static application scenario

Because static is shared by instance objects of the class, if a certain Member variables are shared by all objects, so this member variable should be defined as a static variable .

So the more common static application scenarios are:

1. Modifying member variables
2. Modifying member methods
3. Static code blocks
4. Modified classes [can only modify internal classes, that is, static internal classes]
5. Static guide package

The above application scenarios will be discussed one after another below...

4. The concept of static variables and instance variables

Static variables:
The member variables modified by static are called static variables [also called class variables], static Variables belong to this class, not to objects.

Instance variables:
Member variables that are not modified by static are called instance variables. Instance variables are instance objects belonging to this class.

Another thing to note is: static is not allowed to be used to modify local variables, don’t ask me what I am asking, because it is stipulated by java!

5. The difference between static variables and instance variables [Key points commonly used]

Static variables:

Static variables do not belong to Any instance object belongs to a class, so there will only be one copy in the memory. During the loading process of the class, the JVM only allocates memory space once for static variables.

Instance variables:

Every time an object is created, member variable memory space will be allocated to each object. Instance variables belong to the instance object. In the memory, the object is created several times. Several member variables.

I believe that all of you have higher IQs than Yichun, and you should all understand the above. The examples given below are purely for entertainment. You don’t need to read them if you understand them. The examples below are for reference only and are just for entertainment and atmosphere. If you are in a hurry, you can skip them!

怎么理解呢?打個(gè)比喻吧...就比方說程序員小王是一個(gè)比較溫柔陽光的男孩子,這1024的這一天,老板閑的沒事,非要拉著程序員小王來玩耍,怎么個(gè)玩法呢?老板和小王一人拿著一把菜刀,規(guī)則很簡(jiǎn)單,互相傷害,一人一刀,你一刀,我一刀....游戲一開始,老板二話不說,跳起來就是一刀,程序員小王二話也沒說反手就是一菜刀回去,這個(gè)時(shí)候老板發(fā)飆了,雙眼瞪得忒大,跳起來又是一刀,這個(gè)時(shí)候程序員小王不敢還手了,就沒動(dòng)手。沒想到老板越來越生猛,左一刀右一刀全程下來差不多砍個(gè)半個(gè)時(shí)....程序員小王一直沒有還過手,因?yàn)樾⊥踔浪抢习?..

這個(gè)程序員小王只會(huì)在老板第一次揮刀的時(shí)候,回老板一刀,之后就不還手了,這個(gè)時(shí)候我們把程序員小王看做是靜態(tài)變量,把老板第一次向小王揮刀看做是類加載,把小王回老板一刀看出是分配內(nèi)存空間,而一人一刀這個(gè)回合過程看成是類加載的過程,之后老板的每一刀都看成是創(chuàng)建一次對(duì)象。

連貫起來就是static變量值在類第一次加載的時(shí)候分配空間,以后創(chuàng)建類對(duì)象的時(shí)候不會(huì)重新分配

之后這個(gè)老板挨了一刀之后躺醫(yī)院了一年,一出院回到公司第一件事就是拉程序員宜春出來玩耍,老板殊不知其然,這個(gè)博主程序員宜春性格異常暴躁,老板遞給程序員宜春一把菜刀,博主宜春一接過菜刀,猝不及防的被老板跳起來就是一刀,程序員宜春痛的嗷了一聲,暴躁的程序員宜春還沒嗷完,在嗷的同時(shí)跳起來就是給老板一刀,接著老板跳起來又是一刀,程序員宜春嗷的一聲又是回一刀,老板跳起來又一刀,程序員宜春嗷的一聲又是回一刀,只要老板沒停程序員宜春就沒停,因?yàn)槌绦騿T宜春知道,就自己這曝脾氣,暴躁起來si都敢摸,肯定有幾個(gè)老鐵知道....

程序員宜春就類似實(shí)例變量,每次創(chuàng)建對(duì)象,都會(huì)為每個(gè)對(duì)象分配成員變量?jī)?nèi)存空間,就像老板來一刀,程序員宜春都會(huì)回一刀這樣子的...

6、訪問靜態(tài)變量和實(shí)例變量的兩種方式

我們都知道靜態(tài)變量是屬于這個(gè)類,而不是屬于是對(duì)象,static獨(dú)立于對(duì)象。

但是各位有木有想過:靜態(tài)成員變量雖然獨(dú)立于對(duì)象,但是不代表不可以通過對(duì)象去訪問,所有的靜態(tài)方法和靜態(tài)變量都可以通過對(duì)象訪問【只要訪問權(quán)限足夠允許就行】,不理解沒關(guān)系,來個(gè)代碼就理解了

public class StaticDemo {

        static int value = 666;

        public static void main(String[] args) throws Exception{
            new StaticDemo().method();
        }

        private void method(){
            int value = 123;
            System.out.println(this.value);
        }

}

猜想一下結(jié)果,我猜你的結(jié)果是123,哈哈是咩?其實(shí)

運(yùn)行結(jié)果: 666

回過頭再去品味一下上面的那段話,你就能非??陀^明了了,這個(gè)思想概念要有只是這種用法不推薦!

因此小結(jié)一下訪問靜態(tài)變量和實(shí)例變量的兩種方法:

靜態(tài)變量:

類名.靜態(tài)變量

對(duì)象.靜態(tài)變量(不推薦)

靜態(tài)方法:

類名.靜態(tài)方法

對(duì)象.靜態(tài)方法(不推薦)

7、static靜態(tài)方法

static修飾的方法也叫做靜態(tài)方法,不知道各位發(fā)現(xiàn)咩有,其實(shí)我們最熟悉的static靜態(tài)方法就是main方法了~小白童鞋:喔好像真的是哦~。由于對(duì)于靜態(tài)方法來說是不屬于任何實(shí)例對(duì)象的,this指的是當(dāng)前對(duì)象,因?yàn)閟tatic靜態(tài)方法不屬于任何對(duì)象,所以就談不上this了。

還有一點(diǎn)就是:構(gòu)造方法不是靜態(tài)方法

8、static靜態(tài)代碼塊

先看個(gè)程序吧,看看自個(gè)是否掌握了static代碼塊,下面程序代碼繼承關(guān)系為 BaseThree——> BaseTwo——> BaseOne

BaseOne類

package com.gx.initializationblock;

public class BaseOne {

    public BaseOne() {
        System.out.println("BaseOne構(gòu)造器");
    }

    {
        System.out.println("BaseOne初始化塊");
        System.out.println();
    }

    static {
        System.out.println("BaseOne靜態(tài)初始化塊");

    }

}

BaseTwo類

package com.gx.initializationblock;

public class BaseTwo extends BaseOne {
    public BaseTwo() {
        System.out.println("BaseTwo構(gòu)造器");
    }

    {
        System.out.println("BaseTwo初始化塊");
    }

    static {
        System.out.println("BaseTwo靜態(tài)初始化塊");
    }
}

BaseThree 類

package com.gx.initializationblock;

public class BaseThree extends BaseTwo {
    public BaseThree() {
        System.out.println("BaseThree構(gòu)造器");
    }

    {
        System.out.println("BaseThree初始化塊");
    }

    static {
        System.out.println("BaseThree靜態(tài)初始化塊");
    }
}

測(cè)試demo2類

package com.gx.initializationblock;

/*
     注:這里的ABC對(duì)應(yīng)BaseOne、BaseTwo、BaseThree 
 * 多個(gè)類的繼承中初始化塊、靜態(tài)初始化塊、構(gòu)造器的執(zhí)行順序
     在繼承中,先后執(zhí)行父類A的靜態(tài)塊,父類B的靜態(tài)塊,最后子類的靜態(tài)塊,
     然后再執(zhí)行父類A的非靜態(tài)塊和構(gòu)造器,然后是B類的非靜態(tài)塊和構(gòu)造器,最后執(zhí)行子類的非靜態(tài)塊和構(gòu)造器
 */
public class Demo2 {
    public static void main(String[] args) {
        BaseThree baseThree = new BaseThree();
        System.out.println("-----");
        BaseThree baseThree2 = new BaseThree();

    }
}

運(yùn)行結(jié)果

BaseOne靜態(tài)初始化塊
BaseTwo靜態(tài)初始化塊
BaseThree靜態(tài)初始化塊
BaseOne初始化塊

BaseOne構(gòu)造器
BaseTwo初始化塊
BaseTwo構(gòu)造器
BaseThree初始化塊
BaseThree構(gòu)造器
-----
BaseOne初始化塊

BaseOne構(gòu)造器
BaseTwo初始化塊
BaseTwo構(gòu)造器
BaseThree初始化塊
BaseThree構(gòu)造器

至于static代碼塊運(yùn)行結(jié)果不是很清晰的童鞋,詳細(xì)講解請(qǐng)看這篇Static靜態(tài)代碼塊以及各代碼塊之間的執(zhí)行順序

以上僅僅是讓各位明確代碼塊之間的運(yùn)行順序,顯然還是不夠的,靜態(tài)代碼塊通常用來對(duì)靜態(tài)變量進(jìn)行一些初始化操作,比如定義枚舉類,代碼如下:

public enum WeekDayEnum {
    MONDAY(1,"周一"),
    TUESDAY(2, "周二"),
    WEDNESDAY(3, "周三"),
    THURSDAY(4, "周四"),
    FRIDAY(5, "周五"),
    SATURDAY(6, "周六"),
    SUNDAY(7, "周日");
 
    private int code;
    private String desc;
 
    WeekDayEnum(int code, String desc) {
        this.code = code;
        this.desc = desc;
    }
 
    private static final Map<Integer, WeekDayEnum> WEEK_ENUM_MAP = new HashMap<Integer, WeekDayEnum>();
 
    // 對(duì)map進(jìn)行初始化
    static {
        for (WeekDayEnum weekDay : WeekDayEnum.values()) {
            WEEK_ENUM_MAP.put(weekDay.getCode(), weekDay);
        }
    }
 
    public static WeekDayEnum findByCode(int code) {
        return WEEK_ENUM_MAP.get(code);
    }
 
    public int getCode() {
        return code;
    }
 
    public void setCode(int code) {
        this.code = code;
    }
 
    public String getDesc() {
        return desc;
    }
 
    public void setDesc(String desc) {
        this.desc = desc;
    }
} 

當(dāng)然不僅僅是枚舉這一方面,還有我們熟悉的單例模式同樣也用到了靜態(tài)代碼塊,如下:

public class Singleton {
    private static Singleton instance;
 
    static {
        instance = new Singleton();
    }
 
    private Singleton() {}
 
    public static Singleton getInstance() {
        return instance;
    }
}

9、static變量與普通變量區(qū)別

static變量也稱作靜態(tài)變量,靜態(tài)變量和非靜態(tài)變量的區(qū)別是:靜態(tài)變量被所有的對(duì)象所共享,在內(nèi)存中只有一個(gè)副本,它當(dāng)且僅當(dāng)在類初次加載時(shí)會(huì)被初始化。而非靜態(tài)變量是對(duì)象所擁有的,在創(chuàng)建對(duì)象的時(shí)候被初始化,存在多個(gè)副本,各個(gè)對(duì)象擁有的副本互不影響。

還有一點(diǎn)就是static成員變量的初始化順序按照定義的順序進(jìn)行初始化。

10、靜態(tài)內(nèi)部類

靜態(tài)內(nèi)部類與非靜態(tài)內(nèi)部類之間存在一個(gè)最大的區(qū)別,我們知道非靜態(tài)內(nèi)部類在編譯完成之后會(huì)隱含地保存著一個(gè)引用,該引用是指向創(chuàng)建它的外圍內(nèi),但是靜態(tài)內(nèi)部類卻沒有。沒有這個(gè)引用就意味著:

1、它的創(chuàng)建是不需要依賴外圍類的創(chuàng)建。
2、它不能使用任何外圍類的非static成員變量和方法。

代碼舉例(靜態(tài)內(nèi)部類實(shí)現(xiàn)單例模式)

public class Singleton {
    
   // 聲明為 private 避免調(diào)用默認(rèn)構(gòu)造方法創(chuàng)建對(duì)象
    private Singleton() {
    }
    
   // 聲明為 private 表明靜態(tài)內(nèi)部該類只能在該 Singleton 類中被訪問
    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getUniqueInstance() {
        return SingletonHolder.INSTANCE;
    }
}

當(dāng) Singleton 類加載時(shí),靜態(tài)內(nèi)部類 SingletonHolder 沒有被加載進(jìn)內(nèi)存。只有當(dāng)調(diào)用 getUniqueInstance()方法從而觸發(fā) SingletonHolder.INSTANCE 時(shí) SingletonHolder 才會(huì)被加載,此時(shí)初始化 INSTANCE 實(shí)例,并且 JVM 能確保 INSTANCE 只被實(shí)例化一次。

這種方式不僅具有延遲初始化的好處,而且由 JVM 提供了對(duì)線程安全的支持。

11、靜態(tài)導(dǎo)包

靜態(tài)導(dǎo)包格式:import static

這兩個(gè)關(guān)鍵字連用可以指定導(dǎo)入某個(gè)類中的指定靜態(tài)資源,并且不需要使用類名調(diào)用類中靜態(tài)成員,可以直接使用類中靜態(tài)成員變量和成員方法

//  Math. --- 將Math中的所有靜態(tài)資源導(dǎo)入,這時(shí)候可以直接使用里面的靜態(tài)方法,而不用通過類名進(jìn)行調(diào)用
//  如果只想導(dǎo)入單一某個(gè)靜態(tài)方法,只需要將換成對(duì)應(yīng)的方法名即可
 
import static java.lang.Math.;
//  換成import static java.lang.Math.max;具有一樣的效果
 
public class Demo {
    public static void main(String[] args) {
 
        int max = max(1,2);
        System.out.println(max);
    }
}

靜態(tài)導(dǎo)包在書寫代碼的時(shí)候確實(shí)能省一點(diǎn)代碼,可以直接調(diào)用里面的靜態(tài)成員,但是會(huì)影響代碼可讀性,所以開發(fā)中一般情況下不建議這么使用。

12、static注意事項(xiàng)

1、靜態(tài)只能訪問靜態(tài)。
2、非靜態(tài)既可以訪問非靜態(tài)的,也可以訪問靜態(tài)的。

13、final與static的藕斷絲連

到這里文章本該結(jié)束了的,但是static的使用始終離不開final字眼,二者可謂藕斷絲連,常常繁見,我覺得還是很有必要講講,那么一起來看看下面這個(gè)程序吧。

package Demo;

class FinalDemo {
    public final double i = Math.random();
    public static double t = Math.random();
}

public class DemoDemo {
    public static void main(String[] args) {

        FinalDemo demo1 = new FinalDemo();
        FinalDemo demo2 = new FinalDemo();
        System.out.println("final修飾的  i=" + demo1.i);
        System.out.println("static修飾的 t=" + demo1.t);
        System.out.println("final修飾的  i=" + demo2.i);
        System.out.println("static修飾的 t=" + demo2.t);

        System.out.println("t+1= "+ ++demo2.t );
//      System.out.println( ++demo2.i );//編譯失敗
      }
}
運(yùn)行結(jié)果:
    final修飾的  i=0.7282093281367935
    static修飾的 t=0.30720545678577604
    final修飾的  i=0.8106990945706758
    static修飾的 t=0.30720545678577604
    t+1= 1.307205456785776

static修飾的變量沒有發(fā)生變化是因?yàn)?span style="color:red">static作用于成員變量只是用來表示保存一份副本,其不會(huì)發(fā)生變化。怎么理解這個(gè)副本呢?其實(shí)static修飾的在類加載的時(shí)候就加載完成了(初始化),而且只會(huì)加載一次也就是說初始化一次,所以不會(huì)發(fā)生變化!

至于final修飾的反而發(fā)生變化了?是不是巔覆你對(duì)final的看法?關(guān)于final詳細(xì)講解博主也準(zhǔn)備好了一篇文章程序員你真的理解final關(guān)鍵字嗎?

ok,文章就先到這里了,希望這篇文章能夠幫助到你對(duì)static的認(rèn)識(shí),若有不足或者不正之處,希望諒解并歡迎批評(píng)指正!

本文來自?java入門?欄目,歡迎學(xué)習(xí)!

The above is the detailed content of Deep understanding of the static keyword. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to iterate over a Map in Java? How to iterate over a Map in Java? Jul 13, 2025 am 02:54 AM

There are three common methods to traverse Map in Java: 1. Use entrySet to obtain keys and values at the same time, which is suitable for most scenarios; 2. Use keySet or values to traverse keys or values respectively; 3. Use Java8's forEach to simplify the code structure. entrySet returns a Set set containing all key-value pairs, and each loop gets the Map.Entry object, suitable for frequent access to keys and values; if only keys or values are required, you can call keySet() or values() respectively, or you can get the value through map.get(key) when traversing the keys; Java 8 can use forEach((key,value)-&gt

Java Optional example Java Optional example Jul 12, 2025 am 02:55 AM

Optional can clearly express intentions and reduce code noise for null judgments. 1. Optional.ofNullable is a common way to deal with null objects. For example, when taking values ??from maps, orElse can be used to provide default values, so that the logic is clearer and concise; 2. Use chain calls maps to achieve nested values ??to safely avoid NPE, and automatically terminate if any link is null and return the default value; 3. Filter can be used for conditional filtering, and subsequent operations will continue to be performed only if the conditions are met, otherwise it will jump directly to orElse, which is suitable for lightweight business judgment; 4. It is not recommended to overuse Optional, such as basic types or simple logic, which will increase complexity, and some scenarios will directly return to nu.

How to fix java.io.NotSerializableException? How to fix java.io.NotSerializableException? Jul 12, 2025 am 03:07 AM

The core workaround for encountering java.io.NotSerializableException is to ensure that all classes that need to be serialized implement the Serializable interface and check the serialization support of nested objects. 1. Add implementsSerializable to the main class; 2. Ensure that the corresponding classes of custom fields in the class also implement Serializable; 3. Use transient to mark fields that do not need to be serialized; 4. Check the non-serialized types in collections or nested objects; 5. Check which class does not implement the interface; 6. Consider replacement design for classes that cannot be modified, such as saving key data or using serializable intermediate structures; 7. Consider modifying

Comparable vs Comparator in Java Comparable vs Comparator in Java Jul 13, 2025 am 02:31 AM

In Java, Comparable is used to define default sorting rules internally, and Comparator is used to define multiple sorting logic externally. 1.Comparable is an interface implemented by the class itself. It defines the natural order by rewriting the compareTo() method. It is suitable for classes with fixed and most commonly used sorting methods, such as String or Integer. 2. Comparator is an externally defined functional interface, implemented through the compare() method, suitable for situations where multiple sorting methods are required for the same class, the class source code cannot be modified, or the sorting logic is often changed. The difference between the two is that Comparable can only define a sorting logic and needs to modify the class itself, while Compar

How to handle character encoding issues in Java? How to handle character encoding issues in Java? Jul 13, 2025 am 02:46 AM

To deal with character encoding problems in Java, the key is to clearly specify the encoding used at each step. 1. Always specify encoding when reading and writing text, use InputStreamReader and OutputStreamWriter and pass in an explicit character set to avoid relying on system default encoding. 2. Make sure both ends are consistent when processing strings on the network boundary, set the correct Content-Type header and explicitly specify the encoding with the library. 3. Use String.getBytes() and newString(byte[]) with caution, and always manually specify StandardCharsets.UTF_8 to avoid data corruption caused by platform differences. In short, by

How to parse JSON in Java? How to parse JSON in Java? Jul 11, 2025 am 02:18 AM

There are three common ways to parse JSON in Java: use Jackson, Gson, or org.json. 1. Jackson is suitable for most projects, with good performance and comprehensive functions, and supports conversion and annotation mapping between objects and JSON strings; 2. Gson is more suitable for Android projects or lightweight needs, and is simple to use but slightly inferior in handling complex structures and high-performance scenarios; 3.org.json is suitable for simple tasks or small scripts, and is not recommended for large projects because of its lack of flexibility and type safety. The choice should be decided based on actual needs.

Java method references explained Java method references explained Jul 12, 2025 am 02:59 AM

Method reference is a way to simplify the writing of Lambda expressions in Java, making the code more concise. It is not a new syntax, but a shortcut to Lambda expressions introduced by Java 8, suitable for the context of functional interfaces. The core is to use existing methods directly as implementations of functional interfaces. For example, System.out::println is equivalent to s->System.out.println(s). There are four main forms of method reference: 1. Static method reference (ClassName::staticMethodName); 2. Instance method reference (binding to a specific object, instance::methodName); 3.

Outlook shortcut for new email Outlook shortcut for new email Jul 11, 2025 am 03:25 AM

How to quickly create new emails in Outlook is as follows: 1. The desktop version uses the shortcut key Ctrl Shift M to directly pop up a new email window; 2. The web version can create new emails in one-click by creating a bookmark containing JavaScript (such as javascript:document.querySelector("divrole='button'").click()); 3. Use browser plug-ins (such as Vimium, CrxMouseGestures) to trigger the "New Mail" button; 4. Windows users can also select "New Mail" by right-clicking the Outlook icon of the taskbar

See all articles