Java 关键字 this、static、super、Static Import、Transient - TongtongLan/Java GitHub Wiki

this关键字

解释(In Java, this keyword is used to refer the current instance of the method on which it is used. )

Java关键字this只能用于方法方法体内。

当一个对象创建后,Java虚拟机(JVM)就会给这个对象分配一个引用自身的指针,这个指针的名字就是this。因此,this只能在类中的非静态方法中使用,静态方法和静态的代码块中绝对不能出现this,并且this只和特定的对象关联,而不和类关联,同一个类的不同对象有不同的this。

static修饰的方法可以直接使用类来调用方法。如果在static修饰的方法中使用this关键字,则这个关键字就无法指向合适的对象。所以,static修饰的方法中不能使用this引用。

Usage of this keyword

  1. Used to refer the current class instance variable

Whenever there is an ambiguity in the instance variable and parameter passed, then this keyword will help in resolving it.

  1. Used to invoke current class default constructor

  2. Used to call Current class methods

  3. Can be used to pass current Java instance as parameter

  4. Used to return current Java instance

用途

this就是指向当前对象本身的一个指针

  1. 在构造方法中调用构造方法。this只能调用一个构造器,且必须将构造器调用置于最起始处,否则会编译错误。(Used to invoke current class default constructor)

  2. 在方法体中,用于代表数据成员。当方法形参或其局部参数与成员变量同名情况下,成员变量被屏蔽,此时可用“this.成员变量”引用成员变量。

当this出现在某个方法体中时,它所代表的对象是不确定的,但是它的类型是确定的,它所代表的对象只能是当前类;只有当这个方法被调用时,它所代表的对象才被确定下来:谁调用这个方法,this就代表谁。

  1. 用于在方法中引用当前方法所属类的当前对象时.(Used to refer the current class instance variable)

return this; //返回当前对象

  1. this也可以表示当前类的句柄 ???

Class className = this.getClass(); // this methodology is preferable in java


static关键字

The static keyword belongs to the class rather than instance of the class. We can simply say that the members belongs to the class itself. As a result, you can access the static member without creating the instance for the class. The static keyword can be applied to variables, methods, blocks and nested class.

static 解释

在Java中并不存在全局变量的概念,但是我们可以通过static来实现一个“伪全局”的概念,在Java中static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,当然也可以修饰代码块。

Java把内存分为栈内存和堆内存,其中栈内存用来存放一些基本类型的变量、数组和对象的引用,堆内存主要存放一些对象。在JVM加载一个类的时候,若该类存在static修饰的成员变量和成员方法,则会为这些成员变量和成员方法在固定的位置开辟一个固定大小的内存区域,有了这些“固定”的特性,那么JVM就可以非常方便地访问他们。同时如果静态的成员变量和成员方法不出作用域的话,它们的句柄都会保持不变。同时static所蕴含“静态”的概念表示着它是不可恢复的,即在那个地方,你修改了,他是不会变回原样的,你清理了,他就不会回来了。

同时被static修饰的成员变量和成员方法是独立于该类的,它不依赖于某个特定的实例变量,也就是说它被该类的所有实例共享。所有实例的引用都指向同一个地方,任何一个实例对其的修改都会导致其他实例的变化。

static 用处

通常创建类时,就是在描述那个类的对象的外观和行为(即状态和实现)。用new操作符创建那个类的对象时,数据存储空间才被分配,其方法才能被外界调用。

  • 只想为某特定域分配单一存储空间,而无需考虑创建对象

  • 希望某个方法不会与包含它的那个类的任何对象实例关联在一起,即使没有创建对象,也可以调用此方法。

main()方法

static 使用

static可以用于修饰成员变量和成员方法,我们将其称之为静态变量和静态方法,直接通过类名来进行访问。

  • static变量(Java static variable)

If we declare a variable with “static” keyword, then it is called as static variable.

static int y=0;

All the instance of the class share the same copy of the variable, a static variable can be accessed directly by calling “<>.<>” without need to create instance for the class.

static修饰的变量我们称之为静态变量,没有用static修饰的变量称之为实例变量,他们两者的区别是:

静态变量是随着类加载时被完成初始化的,它在内存中仅有一个,且JVM也只会为它分配一次内存,同时类所有的实例都共享静态变量,可以直接通过类名来访问它。

但是实例变量则不同,它是伴随着实例的,每创建一个实例就会产生一个实例变量,它与该实例同生共死。

所以我们一般在这两种情况下使用静态变量:对象之间共享数据、访问方便。

  • static方法(Java static method)

static方法就是没有this的方法——《Java编程思想》

If we declare a method with “static” keyword, then the method is called as static method.

  • The static method belongs to class rather than object.

  • A static method can access static varaibles directly and it cannot access non-static variables.

  • A static method can only call a static method directly and it cannot call a non-static method from it.

  • super and this keyword cannot be used in a static method.

  • A static method can be directly called by using the class name <>.<> rather than object. This is the main reason we have declared our main() method as static. If not the JVM has to create object first and call the main() method which causes the problem of having extra memory allocation.

static修饰的方法我们称之为静态方法,我们通过类名对其进行直接调用。由于他在类加载的时候就存在了,它不依赖于任何实例,所以static方法必须实现,也就是说他不能是抽象方法abstract。

Static方法是类中的一种特殊方法,我们只有在真正需要他们的时候才会将方法声明为static。如Math类的所有方法都是静态static的。

  • static代码块(Java static block)

The static block, is a block of code inside a Java class that will be executed when a class is first loaded in to the JVM. Mostly the static block will be used for initializing the variables.

被static修饰的代码块,我们称之为静态代码块,静态代码块会随着类的加载一块执行,而且他可以随意放,可以存在于该了的任何地方。

  • Can a static block exist without a main() method ?

The answer is Yes. You can have static block alone in the class without a main method. We all know dynamic loading of a class using Class.forName which we mostly use while loading our JDBC drivers. When we look into the Driver class it will have only the static block and nothing else.

the Driver class of MySql.

public class Driver extends NonRegisteringDriver implements java.sql.Driver 
{

static 
{
    try 
    {
        java.sql.DriverManager.registerDriver(new Driver());
    } catch (SQLException E) 
    {
        throw new RuntimeException("Can't register driver!");
    }
}

public Driver() throws SQLException 
{
    // Required for Class.forName().newInstance()
}
}

As we all know that static block gets executed while loading of the class, so when the Driver class is loaded it actually passes its object to the registerDriver() method of DriverManager class.

  • Java static class

In Java only nested classes are allowed to be declared as static, if we declare a top level class as static then it will throw error. Even though static classes are nested inside a class, they doesn’t need the reference of the outer class they act like outer class only whereas on the other hand non-static nested class need reference of the outer class.

code example

public class Users 
{

static class VipUsers
{
    public void displayVipUsers()
    {
        System.out.println("Welcome Vip User");
    }
}

class NormalUsers
{
    public void displayNormalUsers()
    {
        System.out.println("Welcome Normal User");
    }
}

public static void main(String args[])
{
    //Nested static class doesn't require instantiation of the outer class
    Users.VipUsers vip = new Users.VipUsers();
    vip.displayVipUsers();
    
    /*Below line will throw error as the non-static class require 
    instantiaion of the outer class
    Users.NormalUsers normal = new Users.NormalUsers();*/
    
    //Nested non-static class require instantiation of the outer class
    Users users = new Users();
    Users.NormalUsers normal = users.new NormalUsers();
    normal.displayNormalUsers();
}
}

In our Users class we have two nested VipUser which is a static class and NormalUser which is a non-static class.

Nested static class doesn’t require the outer class to be instantiated and hence we can create instance for the inner static class directly. Like below

Users.VipUsers vip = new Users.VipUsers();

Nested non-static class requires the outer class to be instantiated first, and inner class object is created on top of it.

Users users = new Users(); Users.NormalUsers normal = users.new NormalUsers();

When we try to a Non-static method just like a static method

Users.NormalUsers normal = new Users.NormalUsers();

error:Must qualify the allocation with an enclosing instance of type Users (e.g. x.new A() where x is an instance of Users).

static 修饰成员在继承时的问题


super关键字

解释

用来在子类中引用直接父类中被屏蔽的成员变量和成员成员方法。

用途(Usage of super keyword)

1. super() invokes the constructor of the parent class.

super() will invoke the constructor of the parent class.Before getting into that we will go through the default behavior of the compiler. Even when you don’t add super() keyword the compiler will add one and will invoke the Parent Class constructor.

如果调用带参父类构造方法,在子类构造方法中要显式调用父类的构造方法,用“super(参数列表)”的方式调用。同时还要注意的一点是:“super(参数列表)”这条语句只能用在子类构造方法体中的第一行。

2. super.variable_name refers to the variable in the parent class.

当子类方法中的局部变量或者子类的成员变量与父类成员变量同名时,也就是子类局部变量覆盖父类成员变量时,用“super.成员变量名”来引用父类成员变量。当然,如果父类的成员变量没有被覆盖,也可以用“super.成员变量名”来引用父类成员变量,不过这是不必要的。

3. super.method_name refers to the method of the parent class.

当子类的成员方法覆盖了父类的成员方法时,也就是子类和父类有完全相同的方法定义(但方法体可以不同),此时,用“super.方法名(参数列表)”的方式访问父类的方法。

final

final keyword can be used along with variables, methods and classes. In this article we will be looking into the following topics.

final variable

A final variable is a variable whose value cannot be changed at anytime once assigned, it remains as a constant forever.

code example

public class Travel 
{

final int SPEED=60;
void increaseSpeed(){  
   SPEED=70;
}  
public static void main(String args[])
{  
   Travel t=new  Travel();  
   t.increaseSpeed();  
}  
}

The above code will give you Compile time error, as we are tying to change the value of a final variable ‘SPEED’.

  • What is a blank final variable ?

A final variable which is not initialized at the time of declaration is known as blank final variable. We must initialize a blank final variable in the constructor else it will throw compilation error. Lets now change the above to initialize the “SPEED” variable through a constructor.

code example

public class Travel 
{

final int SPEED;
Travel()
{
    SPEED = 60;
}
public static void main(String args[])
{  
   Travel t=new  Travel();  
   System.out.println("Travelling Speed is :"+t.SPEED);
}  
}
  • what is Static blank final variable?

A static final variable is a variable which is also not initialized at the time of declaration. It can be initialized only in static block.

code example

public class Employee
{
public static final int SOCIAL_SECURITY_NUMBER;
static
{
    SOCIAL_SECURITY_NUMBER = 1234;
}
public static void main(String args[])
{
    Employee e1 = new Employee();
    System.out.println("Social Security Number of Emploee e1 : "+e1.SOCIAL_SECURITY_NUMBER);
}
}

final method

When you declare a method as final, then it is called as final method. A final method cannot be overridden.

code example

class Parent
{

public final void disp()
{
    System.out.println("disp() method of parent class");
}

}

public class Child extends Parent
{

public void disp()
{
    System.out.println("disp() method of child class");
}

public static void main(String args[])
{
    Child c = new Child();
    c.disp();
}

}

Output : We will get the below error as we are overriding the disp() method of the Parent class.

  • Can a final method be inherited ?

Yes, the final method can be inherited but cannot be overridden.

final class

A final class cannot be extended(cannot be subclassed),

lets take a look into the below example

final class Parent
{

}

public class Child extends Parent
{

public static void main(String args[])
{
    Child c = new Child();
}
}

Output :We will get the compile time error like “The type Child cannot subclass the final class Parent”

Java Static Import

The static import is a new feature which is added in Java 5 through which we can access any static member of a class directly. There is no need to qualify it by the class name. For example we can use “System.out.println()” directly with out prefixing System class like “out.println” (As out is a static member of System class).

code example

import static java.lang.System.*;

public class StaticImportExample 
{
public static void main(String args[])
{
    //With out static import
    System.out.println("\"out\" member of \"System\" class without static import");
    System.err.println("\"err\" member of \"System\" class without static import");
    
    //Using static import
    out.println("\"out\" member of \"System\" class with static import");
    err.println("\"err\" member of \"System\" class with static import");
}
}

Note :

Important point to be noted here is that we need to add static keyword in the import statement

‘import static java.lang.System.’ and not like ‘import java.lang.System.

Transient Keyword

What is the use of Java Transient Keyword – Serailization Example

问题

  • java 类加载顺序?

  • static 修饰的部分的存储方式?

引用

Java关键字this、super使用总结

⚠️ **GitHub.com Fallback** ⚠️