java对象之间的调用问题

2021/01/18 Java基础知识 共 3794 字,约 11 分钟
闷骚的程序员

1. 构造方法的调用

  1. 构造方法调用时,必须连同关键字new一起调用。
  2. 构造方法是每个类必须的。一个类至少有一个无参构造,如果不显式编写构造方法,则java编译器会默认为类生成一个无参构造。
  3. 构造方法不能是static的,也不能被继承(默认分情况,私有静态构造不继承)。当然也就不能被覆盖。
  4. 构造方法可以被重载,也可以存在各种访问控制符。
package zeh.myjavase.code17staticandnotstatic;

public class Demo01Constructor {

    public Demo01Constructor() {
        System.out.println("实例化 Demo01Constructor");
    }

    public void help() {
        System.out.println("Demo01Constructor 的help方法");
    }

    public static void main(String[] args) {
        // 通过 new 关键字调用目标类的构造方法,用于实例化目标类的对象。
        // 实例化目标类对象后,就可以通过对象去调用目标类中的成员和方法。
        new Demo01Constructor().help();
    }
}

执行结果:

实例化 Demo01Constructor
Demo01Constructor 的help方法

2. 普通方法的调用

  1. 普通方法可以是static的,也可以是非static的。
  2. 普通方法可以使用各种访问控制符和修饰符。
  3. 普通方法可以被继承,可以被覆盖,可以被重载。
  4. 普通方法的调用通过 “类名.方法名()” 或者 “对象名.方法名()” 进行调用。
package zeh.myjavase.code17staticandnotstatic;

public class Demo02Method {

    public void help() {
        System.out.println("普通非静态方法");
    }

    public static void helpStatic() {
        System.out.println("普通静态方法");
    }

    public static void main(String[] args) {
        // 实例化一个 Demo02Method 对象,通过该对象调用其普通方法
        new Demo02Method().help();

        // 直接通过类名调用其静态方法
        Demo02Method.helpStatic();
    }
}

执行结果:

普通非静态方法
普通静态方法

3. 详解static方法和实例方法的互相调用问题

调用包括对变量(成员变量,方法变量)和成员方法的调用。
调用总的划分为4种方式:

  1. 静态方法调用非静态方法和非静态成员变量
  2. 静态方法调用静态方法和静态成员变量
  3. 非静态方法调用静态方法和静态成员变量
  4. 非静态方法调用非静态方法和非静态成员变量

3.1 静态方法调用非静态方法和非静态成员变量

同一个类中,多个类之间:
必须实例化目标类的对象,通过“对象名.”进行实例方法和实例成员的调用。

注意:static方法和static代码块中不能直接使用this和super,也无法直接使用实例对象,如果要等价使用this或者super,则必须实例化自身对象或者直接父类对象。
原因分析:
原因:static成员是类成员,随着目标类的装载而被初始化,并不随着目标类的new实例化而初始化。即static成员是最早被JVM初始化的,属于静态初始化,而不是new操作进行的动态初始化。
因此,如果强制在static中使用this或者super的话,此时堆内存并没有开辟空间保存当前类的实例化对象或者父类的实例化对象,那this和super根本就不存在指向的内存空间,故而无法直接使用。
static成员只要类一经加载就会在方法区内存的静态区分配空间保存;而非静态成员不进行对象的实例化操作便不会分配空间保存。
所以,在一个类的静态成员中去访问非静态成员之所以会出错是因为在类的非静态成员不存在的时候静态成员就已经存在了,访问一个内存中不存在的东西当然会出错。
案例1:static 方法调用非static方法

package zeh.myjavase.code17staticandnotstatic;

public class Demo03StaticCallNot {

    public void help() {
        System.out.println("普通实例方法");
    }

    public static void main(String[] args) {
        // static方法要调用非静态的方法,则需要new一个目标类对象才能对其调用。
        new Demo03StaticCallNot().help();
    }
}

执行结果:

普通实例方法

案例2:static方法调用非static方法,无法直接使用实例对象,必须在当前static作用域内部手动实例化目标对象才能调用

package zeh.myjavase.code17staticandnotstatic;

public class Demo03StaticCallNot {

    // static作用域外部实例化目标类的对象
    private Demo03StaticCallNot demo03StaticCallNot = new Demo03StaticCallNot();

    public void help() {
        System.out.println("普通实例方法");
    }

    public static void main(String[] args) {
        // 尝试在static作用域内部直接使用一个实例对象,编译报错
        // 提示:Non-static field 'demo03StaticCallNot' cannot be referenced from a static context
        demo03StaticCallNot.help();
    }
}

案例3:同上,static作用域中也不能直接使用this或者super,否则编译错误

package zeh.myjavase.code17staticandnotstatic;

public class Demo03StaticCallNot {

    public void help() {
        System.out.println("普通实例方法");
    }

    public static void main(String[] args) {

        // 提示 'zeh.myjavase.code17staticandnotstatic.Demo03StaticCallNot.super' cannot be referenced from a static context
        this.help();
        super.clone();

    }
}

3.2 静态方法调用静态方法和静态成员变量

同一个类中:可以直接调用;可以通过“当前类名.”调用;可以实例化自身对象后通过”对象名.”调用。
多个类之间:“目标类名.”调用;实例化目标对象后“目标对象名.”调用。

package zeh.myjavase.code17staticandnotstatic;

public class Demo04StaticCallStatic {

    public static void help(){
        System.out.println("static方法");
    }

    public static void main(String[] args) {
        // 直接调用即可
        Demo04StaticCallStatic.help();
    }
}

执行结果:

static方法

3.3 非静态方法调用静态方法和静态成员变量

同一个类中:可以直接调用;可以通过“当前类名.”调用;可以实例化自身对象后通过”对象名.”调用。
多个类之间:“目标类名.”调用;实例化目标对象后“目标对象名.”调用。

package zeh.myjavase.code17staticandnotstatic;

public class Demo05NotStaticCallStatic {

    public static void help1() {
        System.out.println("static 方法");
    }

    public void help2() {
        // 实例方法调用静态方法
        Demo05NotStaticCallStatic.help1();
    }

    public static void main(String[] args) {
        new Demo05NotStaticCallStatic().help2();
    }
}

执行结果:

static 方法

3.4 非静态方法调用非静态方法和非静态成员变量

同一个类中:可以直接调用;可以实例化自身对象后通过“对象名.”调用。
多个类之间:实例化目标对象后通过“对象名.”调用。

package zeh.myjavase.code17staticandnotstatic;

public class Demo06NotStaticCallNot {

    public void help1() {
        System.out.println("实例方法1");
    }

    public void help2() {
        // 实例化目标对象进行调用
        new Demo06NotStaticCallNot().help1();
        System.out.println("实例方法2");
    }

    public static void main(String[] args) {
        new Demo06NotStaticCallNot().help2();
    }
}

执行结果:

实例方法1
实例方法2

文档信息

Search

    Table of Contents