Home  >  Article  >  Java  >  Detailed explanation of the functions of protected modifier and static modifier in Java programming

Detailed explanation of the functions of protected modifier and static modifier in Java programming

高洛峰
高洛峰Original
2017-01-24 15:32:121669browse

protected
Let’s talk about protected access rights. Look at Example 1 below:
Test.java

class MyObject {}
  
public class Test {
  public static void main(String[] args) {
    MyObject obj = new MyObject();
    obj.clone(); // Compile error.
  }
}

At this time the error mentioned above appears: The method clone from the type Object is not visiuable.
We have Clearly Object.clone() is a protected method. This shows that this method can be accessed by the same package (java.lang) and its (java.lang.Object) subclasses. Here is the MyObject class (which inherits from java.lang.Object by default).
Similarly, Test is also a subclass of java.lang.Object. However, protected methods of one subclass cannot be accessed from another subclass, even though the two subclasses inherit from the same parent class.
Look at Example 2 again:
Test2.java

class MyObject2 {
  protected Object clone() throws CloneNotSupportedException {
    return super.clone();
  }
}
  
public class Test2 {
  public static void main(String[] args) throws CloneNotSupportedException {
    MyObject2 obj = new MyObject2();
    obj.clone(); // Compile OK.
  }
}

Here, we override (override) the clone() method of the parent class in the MyObject2 class, and in another class The clone() method is called in Test2 and the compilation passes.
The reason why the compilation passes is obvious. When you override the clone() method in the MyObject2 class, the MyObject2 class and the Test2 class are in the same package, so this protected method is visible to the Test2 class.
At this point in the analysis, we are recalling the statement in Chapter 2.2 of the shallow copy and deep copy article in Java. ② Override the clone() method of the base class in the derived class and declare it as public. Now you understand the reason for this sentence (in order to allow other classes to call the clone() method of this class, the properties of the clone() method must be set to public after overloading).
Let’s look at Example 3:
Test3.java

package 1
class MyObject3 {
protected Object clone() throws CloneNotSupportedException {
    return super.clone();
  }
}
  
package 2
public class Test3 extends MyObject3 {
  public static void main(String args[]) {
    MyObject3 obj = new MyObject3();
    obj.clone(); // Compile error.
    Test3 tobj = new Test3();
    tobj.clone();// Complie OK.
  }
}

Here I use the Test3 class to inherit MyObject3. Note that these two classes are different packages , otherwise it is the situation in Example 2. In the Test3 class, the clone() method of the instance tobj of the Test3 class is called, and the compilation passes. When the clone() method of instance obj of the MyObject3 class is also called, a compilation error occurs!
Unexpected result, can't protected methods be accessed by inherited classes?
It must be clear that class Test3 does inherit class MyObject3 (including its clone method), so you can call your own clone method in class Test3. But the protected method of class MyObject3 is invisible to its different subclass Test3.

Method access control:

Detailed explanation of the functions of protected modifier and static modifier in Java programming

static
1. Keyword static (remember these first, then read on)
1) Static methods and static variables belong to a certain class, not objects of the class.
2) References to static methods and static variables are directly referenced through the class name.
3) Non-static methods and non-static member variables cannot be called in static methods. On the contrary, it is OK.
4) Static variables are similar to global variables in other languages ​​in a certain program. If they are not private, they can be accessed outside the class.
2. When to use static
When we create an instance of a class (object), we usually use the new method so that the data space of this class can be created and its methods can be called.
However, sometimes we hope that although a class can create n objects (obviously the data spaces of these n objects are different), some data of these n objects are the same, that is, regardless of the class How many instances are there for which there is a memory copy of this data (see Example 1). This is the case with static variables.
Another situation is when you want a method not to be associated with any object of the class that contains it. In other words, this method can be called even if the object is not created. An important use of static methods is that they can be called without creating any objects (see Example 2). This is the case with static methods.
There is also a special usage that occurs in inner classes. Usually an ordinary class is not allowed to be declared static, only an inner class can. At this time, the inner class declared as static can be used directly as a normal class without instantiating an outer class (see Example 3). This is the case with static classes.
Example 1

public class TStatic {
  static int i;
  
  public TStatic() {
    i = 4;
  }
  
  public TStatic(int j) {
    i = j;
  }
  
  public static void main(String args[]) {
    System.out.println(TStatic.i);
    TStatic t = new TStatic(5); // 声明对象引用,并实例化。此时i=5
    System.out.println(t.i);
    TStatic tt = new TStatic(); // 声明对象引用,并实例化。此时i=4
    System.out.println(t.i);
    System.out.println(tt.i);
    System.out.println(t.i);
  }
}

Result:

0
5
4
4
4

static variables are created when the class is loaded, and static variables exist as long as the class exists. They must be initialized when defined. In the above example, i is not initialized, so the default initial value 0 will be obtained. Static variables can only be initialized once, and static variables only receive the last initialization.
Actually, this is still a problem of multiple instances sharing a static variable.

Example 2
Not declared as static

class ClassA {
  int b;
  
  public void ex1() {}
  
  class ClassB {
    void ex2() {
      int i;
      ClassA a = new ClassA();
      i = a.b; // 这里通过对象引用访问成员变量b
      a.ex1(); // 这里通过对象引用访问成员函数ex1
    }
  }
}


Declared as static

class ClassA {
  static int b;
  
  static void ex1() {}
}
  
class ClassB {
  void ex2() {
    int i;
    i = ClassA.b; // 这里通过类名访问成员变量b
    ClassA.ex1(); // 这里通过类名访问成员函数ex1
  }
}

在使用静态方法时要注意,在静态方法中不能调用非静态的方法和引用非静态的成员变量(在static方法中也不能以任何方式引用this或super)。理由很简单,对于静态的东西,JVM在加载类时,就在内存中开辟了这些静态的空间(所以可以直接通过类名引用),而此时非静态的方法和成员变量所在的类还没有实例化。
所以如果要使用非静态的方法和成员变量,可以直接在静态方法中实例化该方法或成员变量所在的类。public static void main就是这么干的。
 
示例3

public class StaticCls {
  public static void main(String[] args) {
    OuterCls.InnerCls oi = new OuterCls.InnerCls();// 这之前不需要new一个OuterCls
  }
}
  
class OuterCls {
  public static class InnerCls {
    InnerCls() {
      System.out.println("InnerCls");
    }
  }
}

 
结果:

InnerCls

3.静态初始化
static定义的变量会优先于任何其它非static变量,不论其出现的顺序如何。静态代码块(在“static{”后面跟着一段代码),是用来进行显式的静态变量初始化,这段代码只会初始化一次,且在类被第一次装载时。看下面示例。

class Value {
  static int c = 0;
  
  Value() {
    c = 15;
  }
  
  Value(int i) {
    c = i;
  }
  
  static void inc() {
    c++;
  }
}
  
class Count {
  public static void prt(String s) {
    System.out.println(s);
  }
  
  Value v = new Value(10);
  
  static Value v1, v2;
  static {
    prt("in the static block of calss Count v1.c=" + v1.c + " v2.c="
       + v2.c);
    v1 = new Value(27);
    prt("in the static block of calss Count v1.c=" + v1.c + " v2.c="
       + v2.c);
    v2 = new Value();
    prt("in the static block of calss Count v1.c=" + v1.c + " v2.c="
       + v2.c);
  }
}
  
public class TStaticBlock {
  public static void main(String[] args) {
    Count ct = new Count();
    Count.prt("in the main:");
    Count.prt("ct.c=" + ct.v.c);
    Count.prt("v1.c=" + Count.v1.c + " v2.c=" + Count.v2.c);
    Count.v1.inc();
    Count.prt("v1.c=" + Count.v1.c + " v2.c=" + Count.v2.c);
    Count.prt("ct.c=" + ct.v.c);
  }
}

 

 
结果:

in the static block of calss Count v1.c=0 v2.c=0
in the static block of calss Count v1.c=27 v2.c=27
in the static block of calss Count v1.c=15 v2.c=15
in the main:
ct.c=10
v1.c=10 v2.c=10
v1.c=11 v2.c=11
ct.c=11

   

不管是v,v1还是v2,它们操作的成员变量都是同一个静态变量c。
在类Count中先初始化v1,v2(static Value v1, v2;),再初始化静态代码块(static{}),最后初始化v。

更多Detailed explanation of the functions of protected modifier and static modifier in Java programming相关文章请关注PHP中文网!

Statement:
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