24、使用 Java 官方教程学习:① 类变量和类方法详解;② 深入介绍 main() 方法

简介: 24、使用 Java 官方教程学习:① 类变量和类方法详解;② 深入介绍 main() 方法


一、引出类变量

需求:有一群小孩👶在玩堆雪人☃️的游戏,不时会有新的小孩加入游戏。请问如何知道现在共有多少人在玩?

public class Child {
    public static int childCnt = 0;
    private String name;
    /**
     * 返回全部的孩子个数
     */
    public int getChildCnt() {
        return childCnt;
    }
    public Child(String name) {
        this.name = name;
        childCnt++;
        System.out.println("【" + this.name + "】小朋友加入了游戏");
    }
}
public class ChildPlaySnowman {
    public static void main(String[] args) {
        System.out.println();
        
        Child qy = new Child("庆医");
        Child hn = new Child("浩男");
        Child ms = new Child("莫松");
        Child wf = new Child("王凡");
        Child lh = new Child("陆昊");
        System.out.println();
        System.out.println("共有 " + qy.getChildCnt() + " 个小孩在玩游戏!");
        System.out.println("共有 " + Child.childCnt + " 个小孩在玩游戏!");
        System.out.println("共有 " + hn.childCnt + " 个小孩在玩游戏!");
    }
}

🔑 被 static 修饰的成员变量叫做类变量(也叫做静态变量、静态字段)

🔑 类变量的值被所有该类的实例共享(所有 Child 类的对象修改 childCnt 变量的值的时候,修改的是同一个 childCnt 变量的值)

🔑 类变量在程序运行过程中只占用一份固定的内存(存储在方法区)

🔑 没有被static修饰的成员变量也叫做实例变量

🔑 类变量可通过类名访问(推荐)

🔑 类变量可通过对象名访问(不推荐)

🔑 类被初始化的时候类变量会被赋予初始值

🔑 当类第一次被主动使用的时候,类会被初始化

二、类变量(Class Variables)

(1) 官方教程

【官方教程地址(类成员)】

🌼 When a number of objects are created from the same class blueprint, they each have their own(属于它们自己的) distinct copies of instance variables.

🌾 使用同一个类的蓝图创建多个对象后,这多个对象有它们自己的独特的实例变量。

🌼 Sometimes,you want to have variables that are common to all objects.

🌾有时候,您希望拥有所有对象共有的变量。

🌼 This is accomplished with the static modifier. Fields that have the static modifier in their declaration are called static fields or class variables.

🌾 这是通过static修饰符完成的。在其声明中具有static修饰符的字段被称为静态字段类变量

🌼 They are associated with the class, rather than with any object. Every instance of the class shares a class variable, which is in one fixed location in memory.

🌾 类变量与类相关联,而不与任何对象相关联。同一个类的每一个实例都共享一个类变量,类变量位于内存中的一个固定的位置。

🌼 Any object can change the value of a class variable, but class variables can also be manipulated without creating an instance of the class.

🌾 同一个类的所有对象都可以改变类变量的值,但类变量的值也可以在不创建任何对象实例的时候被操纵。

(2) 类变量细节

✏️ ① 当需要让某个类的所有对象共享一个变量的时候,可以考虑使用类变量(静态变量)

✏️ ② 类变量是该类的所有对象共享的,而实例变量是每个对象独享的

✏️ ③ 被static修饰的称为类变量或静态变量,否则称为实例变量或属性

✏️ ④ 类变量在类加载(类被初始化:第一次主动使用类)的时候有初始值(即使没有创建对象,只要类被初始化了,类变量就有值了)

三、类方法

(1) 类方法知识点罗列

🌼 The Java programming language supports static methods as well as static variables. Static methods, which have the static modifier in their declarations, should be invoked with the class name, without the need for creating an instance of the class.

🌾 Java 语言支持静态方法(类方法)和静态变量(类变量)。方法声明的时候有static关键字的是静态方法,静态方法应该通过类名来调用,无需创建一个类的实例。

🌼 You can also refer to static methods with an object reference,

but this is discouraged because it does not make it clear that they are class methods.

🌾 你也可以通过对象引用来调用静态方法,但并不鼓励这样做,因为它没有明确说明它们是类方法

🌼 A common use for static methods is to access static fields.

🌾 静态方法的一个常见用途是访问静态字段。


🌼 ① Instance methods can access instance variables and instance methods directly. 实例方法可以直接访问实例变量和调用实例方法。

🌼 Instance methods can access class variables and class methods directly. 实例方法可以直接访问变量和调用方法。

class MethodAccessDemo {
    public static int staticVar = 666;
    private String instanceVar = "庆医";
    public int instanceMethod1() {
        // instanceVar = 庆医
        System.out.println("instanceVar = " + instanceVar);
        // staticVar = 666
        System.out.println("staticVar = " + staticVar);
        // instanceMethod2()
        instanceMethod2();
        // staticMethod()
        staticMethod();
        return staticVar;
    }
    private static void staticMethod() {
        System.out.println("staticMethod()");
    }
    public void instanceMethod2() {
        System.out.println("instanceMethod2()");
    }
}
public class Demo {
    public static void main(String[] args) {
        MethodAccessDemo instance = new MethodAccessDemo();
        int cnt = instance.instanceMethod1();
        // staticVar = 666
        System.out.println("staticVar = " + cnt);
    }
}

🌼 Class methods can access class variables and class methods directly. 类方法可以直接访问类变量和调用类方法。

🌼 Class methods cannot access instance variables or instance methods directly.【they must use an object reference. Also, class methods cannot use the this keyword as there is no instance for this to refer to】 类方法不能直接访问实例变量和调用实例方法。【在类方法中必须使用对象引用才能够访问实例变量和调用实例方法,并且类方法中不能使用this关键字,因为没有实例对象让this去引用】

(2) 案例(统计捐款金额)

📜 疫情无情,人有情。一方有难,八方支援。新冠病毒☠️肆虐我的家乡,为了帮助我们抗击疫情, 很多人用金钱给予帮助。请编写一个程序,统计总共捐款金额。

/**
 * 捐款者
 */
class Donor {
    private static double totalMoney;
    private String name;
    public Donor(String name) {
        this.name = name;
    }
    public void donate(double val) {
        if (val <= 0) {
            System.out.println("金额必须大于0");
            return;
        }
        System.out.println("\n感谢【" + name + "】资助 " + val + " 元");
        totalMoney += val;
    }
    public static double getTotalMoney() {
        return totalMoney;
    }
}
public class Demo {
    public static void main(String[] args) {
        Donor wf = new Donor("王凡");
        wf.donate(10000);
        Donor zhn = new Donor("张浩男");
        zhn.donate(99999);
        Donor qy = new Donor("庆医");
        qy.donate(800);
        // 总共收到捐款金额:110799.0
        System.out.println("\n总共收到捐款金额:" + Donor.getTotalMoney());
    }
}

(3) 类方法使用场景

✏️ 当某个方法中的代码不涉及任何与对象相关的成员的时候,可以考虑将该方法设计为静态方法

✏️ 如果希望不创建类的实例也可以调用该方法,可考虑将该方法设计为静态方法

✏️ 如 jdk 中的 MathArraysCollections

✏️ 工具类中的方法可以考虑设计为静态方法

(4) 类方法注意事项

📖 类方法和实例方法都是随着类的加载而加载的,方法的结构信息存储在方法区。this是一个隐藏的、位置最靠前的方法参数,this是指向当前对象的引用,this与实例相关。类方法中是不能使用this的【类方法可以通过类名调用,也许通过类名调用类方法的时候对象根本就没有创建(对象没有创建就不可能存在this)】

📖 实例方法的方法参数中隐藏着一个位置最靠前的方法参数this(它指向调用该方法的对象)

📖 实例方法和对象相关,只能通过对象名调用,不能通过类名调用

📖 类方法可以通过类名调用,也可以通过对象名调用

四、类变量和类方法 Exercise

第 ① 题

看下面的代码, 分析打印结果是什么?

public class Demo {
    static int count;
    public void count() {
        System.out.println("count = " + (count++));
    }
    public static void main(String[] args) {
        // count = 0
        new Demo().count();
        // count = 1
        new Demo().count();
        // 2
        System.out.println(Demo.count);
    }
}

第 ② 题

看下面的代码, 修改错误,并思考打印结果:

class Person {
    private int id;
    private static int total;
    public static int getTotalPerson() {
    /*
      1.id 是实例变量
      2.getTotalPerson() 是静态方法
      3.静态方法中不能够直接访问实例成员
     */
        // id++; // ERROR
        return total;
    }
    public Person() {
    /*
      1.total 类变量
      2.Person() 是构造方法, 构造方法是和实例相关的
      3.在构造方法中可以直接访问类变量
     */
        total++;
        id = total;
    }
}
public class TestPerson {
    public static void main(String[] args) {
        // total = 0
        System.out.println("total = " + Person.getTotalPerson());
    /*
      创建 Person 对象会调用构造方法, 构造方法的调用会使得 total 的值
      变为1, id 的值也变为1
     */
        new Person();
        // total = 1
        System.out.println("total = " + Person.getTotalPerson());
    }
}

第 ③ 题

看下面的代码, 修改错误,并思考打印结果:

class Person {
    private int id;
    public static int total;
    public static void setTotalPerson(int total) {
    /*
        1.setTotalPerson() 是类方法
      2.类方法中坚决不能使用 this 关键字
     */
        // this.total = total; // ERROR
        Person.total = total;
    }
    public Person() {
        total++;
        id = total;
    }
}
public class TestPerson {
    public static void main(String[] args) {
        Person.setTotalPerson(1);
        new Person();
        // 2
        System.out.println(Person.total);
    }
}

五、深入介绍 main() 方法

(1) 电影 Hello World

❤️ 即使世界毁灭,我也想再见你一面 ❤️

❤️为了再见你一面,我愿意重启整个世界❤️

这是日本动画电影《Hello World》里面的台词

✏️ 在京都居住的16岁内向男高中生👦直实的面前,突然出现从10年后穿越而来的自己。

✏️ 未来的直实告诉他,自己不久便会与瑠璃相爱,可是之后烟花🎆大会时瑠璃却会因为一场事故意外成为植物人。

✏️ 一心为拯救初恋的直实与十年后的自己并肩作战,卷入了这场现实与虚拟的记忆世界,经历了一系列超乎想象的事情。

✏️ 原本怯懦的高中生直实燃生了即使世界毁灭,我也想再见你一面的勇气。

✏️ 十年后穿越而来的直实也终于说出了深藏心底的那句我一直爱你 …

赶快去看看吧!🍀① 为了浪漫的台词【即使世界毁灭,我也想再见你一面;为了再见你一面,我愿意重启整个世界】;🍀② 为了刻在程序开发者心中的 Hello World!

(2) Hello World!

📃 学习一门新的编程语言的时候,大多数人的第一个程序一般都是【Hello World】,Java 的【HelloWorld】程序如下所示:

public class HelloWorld {
    public static void main(String[] args) {
        // Hello World!
        System.out.println("Hello World!");
    }
}

📃 当你第一次编写并运行了 Java 中的【HellowWorld】程序后,你便用 Java 语言和计算机打了一个招呼,有了一个美好的邂逅。

📃 这美好的邂逅是在 Java 的入口方法main()方法中进行的

📃 但对main()方法还没有一个完美的介绍

📃 下面深入介绍一下 Java 的入口方法:

public static void main(String[] args){}

(3) 深入介绍 main() 方法

public class HelloWorld {
    public static void main(String[] args) {
        for (int i = 0; i < args.length; i++) {
            System.out.println("parameter" + (i + 1) + ": " + args[i]);
        }
    }
}

📖 ① public:JVM 需要调用类的 main() 方法 (入口方法),所以该方法的访问权限必须是public

📖 ② static:JVM 调用main()方法的时候无需创建对象,所以是static

📖 ③ String[]main()方法接收 String 数组类型的参数,该数组中保存了执行 java 命令时传递的参数

👑 java 命令:运行 class 文件

👑 love、study、handsome 被放在字符串数组 args

👑 参数名 args 只是一个标识,写成其他的参数名也是可以的(下面的代码把 args 改为了 canShu 也是正确的)

public class HelloWorld {
    public static void main(String[] canShu) { 
        for (int i = 0; i < canShu.length; i++) {
            System.out.println("parameter" + (i + 1) + ": " + canShu[i]);
        }
    }
}

📖 ④ 在 main() 方法中可以直接调用 main() 方法所在类的静态方法或访问静态属性,但不能直接访问或调用实例成员,只有创建该类的对象后才能访问实例成员

结束!若有错误,请不吝赐教!

相关文章
|
3天前
|
自然语言处理 Java API
Java 8的Stream API和Optional类:概念与实战应用
【5月更文挑战第17天】Java 8引入了许多重要的新特性,其中Stream API和Optional类是最引人注目的两个。这些特性不仅简化了集合操作,还提供了更好的方式来处理可能为空的情况,从而提高了代码的健壮性和可读性。
26 7
|
1天前
|
并行计算 Java API
Java 8中的接口默认方法和静态方法以及并行数组
【5月更文挑战第19天】Java 8引入了许多新特性,其中包括接口的默认方法和静态方法,以及并行数组的能力。这些特性增强了Java的面向对象编程模型和数组处理能力。让我们深入了解它们的概念和实践。
19 2
|
2天前
|
安全 Java 容器
Java一分钟之-并发编程:线程安全的集合类
【5月更文挑战第19天】Java提供线程安全集合类以解决并发环境中的数据一致性问题。例如,Vector是线程安全但效率低;可以使用Collections.synchronizedXxx将ArrayList或HashMap同步;ConcurrentHashMap是高效线程安全的映射;CopyOnWriteArrayList和CopyOnWriteArraySet适合读多写少场景;LinkedBlockingQueue是生产者-消费者模型中的线程安全队列。注意,过度同步可能影响性能,应尽量减少共享状态并利用并发工具类。
16 2
|
2天前
|
Java 编译器
滚雪球学Java(34):探究Java方法的神奇魔法和参数传递奥秘
【5月更文挑战第9天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
10 1
滚雪球学Java(34):探究Java方法的神奇魔法和参数传递奥秘
|
3天前
|
Java
Java中int[]与Integer[]相互转化的方法,java基础知识面试重点总结
Java中int[]与Integer[]相互转化的方法,java基础知识面试重点总结
|
4天前
|
设计模式 算法 Java
Java的前景如何,好不好自学?,万字Java技术类校招面试题汇总
Java的前景如何,好不好自学?,万字Java技术类校招面试题汇总
|
5天前
|
Java
Java String 避免空指针的方法
Java String 避免空指针的方法
5 0
|
Java
Java中的main()方法详解
Java中的main()方法详解 转自 http://lavasoft.blog.51cto.com/62575/53263   在Java中,main()方法是Java应用程序的入口方法,也就是说,程序在运行的时候,第一个执行的方法就是main()方法,这个方法和其他的方法有很大的不同,比如方法的名字必须是main,方法必须是public static void 类型的,方法必须接收一个字符串数组的参数等等。
778 0
|
3天前
|
Java 测试技术
Java多线程的一些基本例子
【5月更文挑战第17天】Java多线程允许并发执行任务。示例1展示创建并启动两个`MyThread`对象,各自独立打印&quot;Hello World&quot;。示例2的`CounterExample`中,两个线程(IncrementThread和DecrementThread)同步地增加和减少共享计数器,确保最终计数为零。这些例子展示了Java线程的基本用法,包括线程同步,还有如Executor框架和线程池等更复杂的用例。
11 0