1. Static method
static method is generally called a static method because static method does not depend on any object It can be accessed, so for static methods, there is no this, because it is not attached to any object. Since there is no object, there is no this. And due to this feature, non-static member variables and non-static member methods of the class cannot be accessed in static methods, because non-static member methods/variables must rely on specific objects before they can be called.
But it should be noted that although non-static member methods and non-static member variables cannot be accessed in static methods, static member methods/variables can be accessed in non-static member methods. A simple example:
In the above code, since the print2 method exists independently of the object, it can be called directly using the class name. If non-static methods/variables can be accessed in static methods, then if there is the following statement in the main method:
MyObject.print2();
There are no objects at this time, str2 does not exist at all, so There will be a conflict. The same is true for methods. Since you cannot predict whether non-static member variables are accessed in the print1 method, accessing non-static member methods in static member methods is also prohibited.
For non-static member methods, there is obviously no restriction on accessing static member methods/variables.
Therefore, if you want to call a method without creating an object, you can set this method to static. Our most common static method is the main method. As for why the main method must be static, it is now clear. Because the program does not create any objects when executing the main method, it can only be accessed through the class name.
Also remember, regarding whether the constructor is a static method, please refer to: http://blog.csdn.net/qq_17864929/article/details/48006835
2. Static variables
static variables are also called static variables. The difference between static variables and non-static variables is: static variables are shared by all objects, and there is only one in the memory. The copy is [stored in the method area], which will be initialized if and only when the class is loaded for the first time [the initialization locations of static variables with final and without final are different]. Non-static variables are owned by objects and are initialized when the object is created. There are multiple copies, and the copies owned by each object do not affect each other.
The initialization order of static member variables is initialized in the order in which they are defined.
3. Static code block
The static keyword also plays a key role in forming a static code block 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 [according to the class loading principle, each class is loaded once using parent delegation loading].
Initialization sequence static code block>Construction code block>Constructor function
public class Client { {//构造代码块 System.out.println("执行构造代码块"); } }
Why static block can be used to optimize program performance is because of its characteristics: it will only be loaded when the class is loaded executed once. Let’s look at 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 to determine whether the person was born between 1946 and 1964. Every time isBornBoomer is called, two objects, startDate and birthDate, will be generated, resulting in a waste of space. If it is changed to this, the efficiency will be better. In fact, it uses the mechanism of loading static code blocks once in memory:
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 performed once are placed in static code block.
4. Static inner classes
This place does not write static inner classes separately, but deepens the understanding of static inner classes by comparing them with ordinary inner classes:
Why use inner classes?
1. Internal classes are generally only used by their external classes; [A good example of being used by external classes is that there is an internal class Entry in the hashmap collection, which is converted to hashmap storage for use]
2. The inner class provides some kind of window into the outer class. The inner class has a reference to the outer class, so the inner class can directly access the properties of the outer class;
3. It is also the most attractive reason. Each Inner classes can independently inherit an interface, regardless of whether the outer class has inherited an interface. Therefore, inner classes make the solution of multiple inheritance more complete.
A class defined inside a class is called an inner class, and a class containing an inner class is called an outer class. Inner classes can declare access restrictions such as public, protected, private, etc., they can be declared abstract for other inner classes or external classes to inherit and extend, or they can be declared static or final, or they can implement specific interfaces.
外部类按常规的类访问方式(以对象的方式)使用内部 类,唯一的差别是外部类可以访问内部类的所有方法与属性,包括私有方法与属性,外部类访问内部类,需要创建对象访问;有一点需要注意,内部类不能访问外部类所在的局部变量,只能访问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. Although this feature is often called "static import", the syntax must be import static, followed by the fully qualified name of the static member you want to import, or a wildcard character. In this example, we make a static import on the out object of the System class.
2. In this example, we may want to use several static members of the java.lang.Integer class. This static import statement uses wildcards to say "I want to do a static import on all static members in 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. Very good! Also, we don't have to type Integer in Integer.MAX_VALUE. So, in this line of code, we are able to use a shortcut for a static method and a constant.
4. Finally, we perform more shortcut operations, this time for methods of the Integer class.
We've been getting a bit sarcastic about this feature, but we're not alone. We don't think saving a few keystrokes makes the code any harder to read, but many developers have asked for it to be added to the language.
The following are several principles for using static import:
You must say import static, not static import.
Beware of ambiguously named static members. For example, if you perform static imports on the Integer class and the Long class, referencing MAX_VALUE will cause a compiler error because both Integer and Long have a MAX_VALUE constant, and Java will not know which MAX_VALUE you are referencing.
You can perform static imports on static object references, constants (remember, they are static or final) and static methods.
Many java training videos, all on the PHP Chinese website, welcome to learn online!
The above is the detailed content of What is java static. For more information, please follow other related articles on the PHP Chinese website!