cool hit counter A comprehensive summary of the role of static in Java_Intefrankly

A comprehensive summary of the role of static in Java


1. In-depth summary

  To quote a user, it is very well said that if someone asks you what static does; if you say static modifies the properties of the class and the methods of the class, people think you are qualified; if it is said that it can constitute a static code block, then people think you are okay; if you say it can constitute a static inner class, then people think you are good; if you said static guide package, then people think you are good.

That people think you're OK.

   Then we'll start with a summary of STATISTICS in each of these areas; then some of the ambiguities and some of the areas that are easy to ask about in an interview.

1) static methods

   static methods are generally called static methods, and since static methods do not depend on any object to be accessed, there is no this for static methods because they are not attached to any object, and since none of them have an object, there is no talk of this. And due to this feature, non-static member variables and non-static member methods of the class cannot be accessed in static methods, as non-static member methods/variables are dependent on concrete objects to be called.

   But note that while non-static member methods and non-static member variables cannot be accessed in static methods, it is possible to access static member methods/variables in non-static member methods. To give a simple example.

   In the above code, since the print2 method exists independently of the object, it can be called directly over the class name. Suppose it is possible to access a non-static method/variable in a static method, then if there is the following statement in the main method.

  MyObject.print2();

  At this point none of the objects are there, str2 doesn't exist at all, so there's a contradiction. The same is true for methods; since you can't predict whether a non-static member variable is accessed in a print1 method, accessing a non-static member method in a static member method is also prohibited.

   And for non-static member methods, it accesses static member methods/variables apparently without restriction.

  So, if you say you want to call a method without creating an object, you can set that method to static. The most common static method we see is the main method, and as to why the main method must be static, it's now clear. Since the program does not create any objects when it executes the main method, the only way to access them is through the class name.

   Also remember that the reference to whether the constructor is a static method can be found at: http://blog.csdn.net/qq_17864929/article/details/48006835

2) static variables

   The difference between static and non-static variables is that a static variable is shared by all objects, has only one copy in memory [stored in the method area], and it is initialized when and only when the class is first loaded [static variables with and without a final are initialized at different locations]. Non-static variables, on the other hand, are owned by the object, are initialized at the time of object creation, and exist in multiple copies, with the copies owned by the individual objects not affecting each other.

   The static member variables are initialized in the order in which they are defined.

3) static code block

   The static keyword has another key role in forming static blocks of code to optimize program performance. The static block can be placed anywhere in the class, and there can be more than one static block in the class. When classes are first loaded, each static block is executed in the order in which they are loaded and will only be executed once [according to the class loading principle Load each class once Use bi-parental delegate loading].

The order of initialization static block of code > tectonic code block > constructor (computing)

public class Client {
     {// Constructing code blocks
        System.out.println(" Execute the construction code block");
    }
}

The reason why static blocks can be used to optimize program performance is because of its property:It will only be executed once when the class is loaded. Here's an example:

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 is used whether the person was born in 1946-1964, and each time isBornBoomer is called, two objects startDate and birthDate are generated, resulting in a waste of space, if changed to this efficiency would be better, in fact, is to take advantage of the mechanism of static code block in memory value loaded once:.

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;
    }
}

   Therefore, many times some initialization operations that only need to be done once are put in static code blocks.

4) Static internal classes

This place is not written separately for static internals, to deepen the understanding of static internals by comparing them with normal internals.

Why use internal classes?

1. Internal classes are generally only used for their outer classes;【 For outside class use is a good point give an example hashmap Assembling There is an internal class Entry even convert to hashmap Storage to use】

2. Internal classes provide some kind of window into the outer class, Internal classes have references to external classes, So the internal class can access the properties of the external class directly;

3. And the most attractive reason, Each internal class can inherit an interface independently, And whether or not the outer class has inherited some interface。 therefore, Internal classes make the multiple inheritance solution complete。

A class defined inside a class is called an internal class, and a class containing an internal class is called an external class. Internal classes can declare public, protected, private and other access restrictions, and can be declared as abstract for other internal or external classes to inherit and extend, or declared as static or final, or can implement specific interfaces.

External classes use internal classes in the usual class access way (as objects), the only difference being that The external class can access all the methods and properties of the internal class, including private methods and properties, and the external class needs to create an object to access the internal class; one thing to note is that the internal class cannot access the local variables where the external class is located, and can only access the local variables modified by final.

give an example: In the method Defining internal classes Then the internal class Inputs to the calling method follow The entry must be final retouch

When defining an internal class within a method, if the internal class calls a variable in the method, then the variable must be declared as a final type. I couldn't figure it out, but then it occurred to me that the reason should be the life cycle, because the variables defined within the method are local variables, and when they leave the method, the variables become useless and are automatically eliminated, whereas an internal class does not become useless when it leaves the method it is in, it has a broader life cycle, which is illustrated by an example below.

(1) Create an instance

OutClass.InnerClassobj=outClassInstance.newInnerClass(); // Note that it is an external class instance.new, internal class

AAA. StaticInner in = new AAA. StaticInner();// note that it's the outer class itself, the static inner class

(2) this in internal classes

internal class in thethis As with the other classes is the reference itself。 When creating internal class objects, It will have some kind of connection to the peripheral object that created it, So it can access all members of the peripheral classes, No special conditions required, can be interpreted as internal classes linking to external classes。 When creating an internal class object with an external class, This inner class object secretly captures a reference to the outer class, thus, Members of peripheral classes can be accessed through this reference。

(3) External classes accessing internal classes

Internal classes are similar to the properties of external classes, so accessing an internal class object always requires a created external class object. The external class object accesses the properties and methods of the internal class via the form 'external class name.this.xxx'. For example. System.out.println("Print in inner Outer.index=" + pouter.this.index); System.out.println("Print in inner Inner.index=" + this.index);

(4) Internal class upward transformation

Internal classes can also have the same upward transition feature as normal classes. There is a place for internal classes when transforming them up to base types, especially interfaces. If the inner class is private, it can only be asked by its outer classes, thus completely hiding the implementation details.

(5) Classes within methods

Classes created within methods (note that classes can also be defined within methods) cannot have access modifiers added to them. Also, the classes inside the methods are not created when the method is called, they are compiled beforehand just the same.

(6) Static internal classes

Defining a static internal class: when defining an internal class, you can prefix it with a permission modifier static. At this point this internal class becomes a static internal class.

commonly referred to as nested classes , when the internal class is static, means.

[1] To create objects of nested classes, objects of their outer classes are not required.

[2] Cannot be removed from nested classes object to access a non-static peripheral class object in the( It is not possible to access non-static members of an external class from the object of a static internal class);

There is another difference between nested classes and normal internal classes: the fields and methods of normal internal classes can only be placed at the external level of the class, so normal internal classes cannot have static data and static fields, nor can they contain nested classes. But you can include all those things in a nested class. That is, static members cannot be declared in a non-static internal class, and static member variables and methods can only be defined in an internal class if it is modified to be a static class.

Also, it is not necessary to bind an instance of a static internal class to an instance of an external class when creating a static internal class. To define a static internal class in an external class, you do not need to use the keyword new to create an instance of the internal class. Static classes and methods belong only to the class itself, and not to the objects of that class, let alone to the objects of other external classes.

(7) Internal class identifier

Each class produces a .class file with the class name as the file name. Similarly, the inner class produces such a .class file, but instead of the class name of the inner class, its name has a strict restriction: the name of the outer class, plus $,plus the inner class name.

Code specific.

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 an external class
        OutClassTest oc1 = new OutClassTest();
         // New a non-static internal class through an object of an external class
        OutClassTest.InnerClass no_static_inner = oc1.new InnerClass();
         // Calling methods of non-static internal classes
        System.out.println(no_static_inner.getKey());

         // Calling static variables of static internal classes
        System.out.println(OutClassTest.InnerStaticClass.static_value);
         // Instantiate internal static classes directly, without relying on external class instances
        OutClassTest.InnerStaticClass inner = new OutClassTest.InnerStaticClass();
         // Calling non-static methods of static internal classes
        System.out.println(inner.getValue());
         // Calling static methods of internal static classes
        System.out.println(OutClassTest.InnerStaticClass.getMessage());
    }

    private class InnerClass {
         // Static members can only be declared or defined in static internal classes
        // private static String tt = "0";
        private int flag = 0;

        public InnerClass() {
             // III. Non-static members of non-static internal classes can access non-static and static variables of external classes
            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");
             // Calling static methods of external classes
            test();
        }

        public  String getKey() {
            return "no-static-inner";
        }
    }

    private static class InnerStaticClass {
         // Static internal classes can have static members, while non-static internal classes cannot have static members.
        private static String static_value = "0";

        private int flag = 0;

        public InnerStaticClass() {
            System.out.println("InnerClass create a:" + a);
             // Static internal classes are not able to access non-static members of external classes
            // 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() {
             // Static internal classes accessing static methods of external classes
            test();
            return 1;
        }

        public static String getMessage() {
            return "static-inner";
        }
    }

    public OutClassTest() {
         // new a non-static internal class
        InnerClass ic = new InnerClass();
        System.out.println("OuterClass create");
    }

}

4) Static guide package

A static import package is a static import of a java package, using import static instead of import static import package is a new feature in JDK1.5.

Normally we import a class with import com..... ClassName; And a static import is this: import static com..... ClassName.*; There is an extra static here, and there is an extra .* after the class name ClassName , which means import the static methods in this class. Of course, it is possible to import just a static method, just replace .* with the static method name. Then, in this class, you can call the static method directly with the method name instead of having to call it with ClassName.methodName.

Benefit: The benefit of this method is that it simplifies some operations, such as the print operation System.out.println(...); It can then be written to a static party

The method print(...), when used directly print(...) It'll be fine. But this method is recommended when there are many repeated calls, and if there are only one or two calls, it's not as convenient as just writing

example: In Java 5, the import statement was enhanced to provide even more powerful keystroke reduction, although some dispute that this came at the cost of readability. This new feature becomes static import. You can use static import when you want to use static members (the feature is available on classes in the API and on your own classes). The following is an example of code before and after static import.

Prior to static import.

public class TestStatic {

public static void main(String[] args) {

System.out.println(Integer.MAX_VALUE);

System.out.println(Integer.toHexString(42));

}

}

After static import. 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));

}

}

Let's look at what will happen in code that uses the static import feature. 1、 Although the feature commonly referred to as“ static import”, But the syntax must beimport static, The back is the same as the one you want to importstatic Fully qualified names of members, Or wildcard。 In this example, We are inSystem genericout Static import on objects。

2. In this example, we may want to use a few static members of the java.lang.Integer class. This static import statement uses a wildcard to say "I want to do a static import on all static members of this class".

3, Now we finally see the benefits of the static import feature! We don't have to type System in System.out.println. Great! Also, we don't have to type Integer in Integer.MAX_VALUE. So, in this line of code, we are able to use the shortcut for a static method and a constant.

4. Finally, we perform more shortcut operations, this time for the methods of the Integer class.

We've been a bit sarcastic about that feature, but it's not just us. We don't think saving a small number of keystrokes will make the code

Hard to read a bit, but many developers have asked for it to be added to the language.

Here are a few principles for using static imports.

You have to say import static, you can't say static import.

Beware of ambiguously named STAT members. For example, if you perform a static import on the Integer and Long classes, referencing MAX_VALUE will cause a compiler error because both Integer and Long have a MAX_VALUE constant and Java won't know which MAX_VALUE you're referencing.

You can do static imports on static object references, constants (remember, they are static or final), and static methods.

II. The misconceptions of the static keyword

1.Does the static keyword change the access rights of members in a class?

   Some beginners confuse the function of static in java with that of the static keyword in C/C++. Just one thing to remember here: unlike static in C/C++, the static keyword in Java does not affect the scope of variables or methods. The only keywords that can affect access in Java are private, public, and protected (including package access). Look at the following example to understand.

   Tip Error"Person.age unobservable", This means thatstatic The keyword does not change the access rights of variables and methods。

2.Can I access static member variables via this?

   While there is no this for static methods, can static member variables be accessed via this in non-static methods? Let's start with an example of what this code outputs.

public class Main {  
    static int value = 33;
 
    public static void main(String[] args) throws Exception{
        new Main().printValue();
    }
 
    private void printValue(){
        int value = 3;
        System.out.println(this.value);
    }
}
 Output 33

  This is where the understanding of team this and static is examined. What does this stand for? This represents the current object, so if you call printValue through new Main(), the current object is the object generated through new Main(). And static variables are enjoyed by objects, so the value of this.value in printValue is undoubtedly 33. The value inside the printValue method is a local variable and cannot be associated with this at all, so the output is 33. Always remember one thing here: just because a static member variable is independent of an object doesn't mean it can't be accessed through the object; all static methods and static variables can be accessed through the object (as long as access rights are sufficient).

3.Can static work on local variables?

   In C/C++ static is allowed to scope local variables, but in Java remember: static is not allowed to be used to modify local variables. Don't ask why, it's a Java syntax rule.

   See the discussion in this blog post for specific reasons: http://www.debugease.com/j2se/178932.html

III. Common written interview questions

   The following list some of the interview written test often encountered in the topic of static keywords, for reference only, if you have something to add welcome the comments below.

1.What is the output of this code below?

public class Test extends Base{
 
    static{
        System.out.println("test static");
    }
     
    public Test(){
        System.out.println("test constructor");
    }
     
    public static void main(String[] args) {
        new Test();
    }
}
 
class Base{
     
    static{
        System.out.println("base static");
    }
     
    public Base(){
        System.out.println("base constructor");
    }
}
base static

   As for why this result, let's not discuss it, first think about the specific execution process of this code, at the beginning of the execution, first to find the main method, because the main method is the entrance to the program, but before the execution of the main method, you must first load the Test class, and in the loading of the Test class found that the Test class inherits from the Base class, so will go to load the Base class first, in the loading of the Base class, found a static block, it will execute the static block. After the Base class is loaded, it proceeds to load the Test class, and then finds that the Test class also has static blocks in it, and executes the static blocks. After loading the required classes, the main method is executed. The execution of new Test() in the main method calls the constructor of the parent class first, then its own constructor. As a result, the above output appears.

2.What is the output of this code?

public class Test {
    Person person = new Person("Test");
    static{
        System.out.println("test static");
    }
     
    public Test() {
        System.out.println("test constructor");
    }
     
    public static void main(String[] args) {
        new MyClass();
    }
}
 
class Person{
    static{
        System.out.println("person static");
    }
    public Person(String str) {
        System.out.println("person "+str);
    }
}
 
 
class MyClass extends Test {
    Person person = new Person("MyClass");
    static{
        System.out.println("myclass static");
    }
     
    public MyClass() {
        System.out.println("myclass constructor");
    }
}
test static
myclass static
person static
person Test
test constructor
person MyClass
myclass constructor

  Similarly, let's still think about the exact execution of this code. The Test class is loaded first, so the static block in the Test class is executed. Then new MyClass() is executed and the MyClass class has not been loaded yet, so the MyClass class needs to be loaded. When loading the MyClass class, it is found that the MyClass class inherits from the Test class, but since the Test class is already loaded, only the MyClass class needs to be loaded, then the static block in the MyClass class will be executed. After loading, the object is generated via the constructor. And when generating the object, the member variables of the parent class must be initialized first, so it will execute Person person = new Person() in Test, and the Person class has not been loaded yet, so it will first load the Person class and execute the static block in the Person class, then execute the constructor of the parent class, which completes the initialization of the parent class, and then it comes to initialize itself, so it will then execute Person person = new Person() in MyClass, and finally execute the constructor of MyClass.

3.What is the output of this code?

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

Recommended>>
1、The Daily Dose The Coinsteal theft stems from a thirdparty tool
2、An algorithm a day adding binary numbers
3、How does the INSUR coin count value increase What are the principles hidden behind the arithmetic curtain
4、Jincheng Group invests in domestic science fiction film Nobel laureate joins script writing
5、Dr Massachusetts Machine Learning Experience in Dry Sharing

    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号