零基础学Java(12)静态字段与静态方法

零基础学Java(12)静态字段与静态方法静态字段与静态方法之前我们都定义的main方法都被标记了static修饰符,那到底是什么意思?下面我们来看看静态字段如果将一个字段定义为static,每个类只有一个这样的字段。而对于非静态的实例

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

静态字段与静态方法

  之前我们都定义的main方法都被标记了static修饰符,那到底是什么意思?下面我们来看看
 

静态字段

  如果将一个字段定义为static,每个类只有一个这样的字段。而对于非静态的实例字段,每个对象都有自己的一个副本。例如,假设需要给每一个员工赋予唯一的标识码。这里给Employee类添加一个实例字段id和一个静态字段nextId

class Employee {
    // 定义静态字段nextId
    private static int nextId = 1;
    private int id;
}

  现在,每一个Employee对象都有一个自己的id字段,但这个类的所有实例将共享一个nextId字段。换句话说,如果有1000个Employee类对象,则有1000个实例字段id,分别对应每一个对象。但是,只有一个静态字段nextId。即使没有Employee对象,静态字段nextId也存在。它属与类,而不属于任何单个的对象。
  下面实现一个简单的方法:

public void setId() {
    id = nextId;
    nextId++;
}

  假定为harry设置员工标识码:

harry.setId();

  harry的id字段被设置为静态字段nextId当前的值,并且静态字段nextId的值加1:

harry.id = Employee.nextId;
Employee.nextId++

 

静态常量

  静态变量使用的比较少,但静态常量却很常用。例如,在Math类中定义一个静态常量:

public class Math {
    ...
    public static final double PI = 3.14159265358979323846;
    ...
}

  在程序中,可以用Math.PI来访问这个常量。
  如果省略关键字staticPI就变成了Math类的一个实例字段。也就是说,需要通过Math类的一个对象来访问PI,并且每一个Math对象都有它自己的一个PI副本。
  你已经多次使用的另一个静态常量是System.out。它在System类中声明如下:

public class System {
    ...
    public static final PrintStream out = ...;
    ...
}

  前面曾经多次提到过,由于每个类对象都可以修改公共字段,所以,最好不要有公共字段。然而,公共常量(即final字段)却没问题。因为out被声明为final,所以,不允许再将它重新赋值为另一个打印流:

System.out = new PrintStream(...);  // ERROR -- out is final

 

静态方法

  静态方法是不在对象上执行的方法。例如,Math类的pow方法就是一个静态方法。表达式Math.pow(x, a)会计算幂x的a次方。在完成运算时,它并不使用任何Math对象。换句话说,它没有隐式参数。
  可以认为静态方法是没有this参数的方法(在一个非静态的方法中,this参数指示这个方法的隐式参数)
  Employee类的静态方法不能访问id实例字段,因为它不能在对象上执行操作。但是,静态方法可以访问静态字段。下面是这样一个静态方法的示例:

public static int getNextId() {
    return nextId;  // returns static field
}

  可以提供类名来调用这个方法:

int n = Employee.getNextId();

  这个方法可以省略关键字static吗?答案是肯定的。但是,这样一来,你就需要通过Employee类对象的引用来调用这个方法。

注意:可以使用对象调用静态方法,这是合法的。例如,如果harry是一个Employee对象,可以用harry.getNextId()代替Employee.getNextId()。不过,这种写法很容易造成混淆,其原因是getNextId方法计算的结果与harry毫无关系。我们建议使用类名而不是对象来调用静态方法。

在下面两种情况下可以使用静态方法:

  • 方法不需要访问对象状态,因为它需要的所有参数都通过显式参数提供(例如:Math.pow)
  • 方法只需要访问类的静态字段(例如:Employee.getNextId)。

 

工厂方法

  静态方法还有另外一种常见的用途。类似LocalDateNumberFormat的类使用静态工厂方法来构造对象。我们之前使用过工厂方法LocalDate.nowLocalDate.ofNumberFormat类如下生成不同风格的格式化对象:

NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance();
NumberFormat percentFormatter = NumberFormat.getPercentInstance();
double x = 0.1;
System.out.println(currencyFormatter.format(x));  // prints $0.10
System.out.printIn(percentFormatter.format(x));  // prints 10%

  为什么NumberFormat类不利用构造器完成这些操作呢?这主要有两个原因:

  • 无法命名构造器。构造器的名字必须与类名相同。但是,这里希望有两个不同的名字,分别得到货币实例和百分比实例。
  • 使用构造器时,无法改变所构造对象的类型。而工厂方法实际上将返回DecimalFormat类的对象,这是NumberFormat的一个子类。
     

main方法

  需要注意,可以调用静态方法而不需要任何对象。例如,不需要构造Math类的任何对象就可以调用Math.pow
  同理,main方法也是一个静态方法。

public class Application {
    public static void main(String[] args) {
        // construct objects here
        ...
    }
}

  main方法不对任何对象进行操作。事实上,在启动程序时还没有任何对象。静态的main方法将执行并构造程序所需要的对象。

  提示:每一个类可以由一个main方法。这是常用于对类进行单元测试的一个技巧
 

例子

  接下来我们创建Employee类,其中有一个静态字段nextId和一个静态方法getNextId。这里将三个Employee对象填入一个数组,然后打印员工信息。最后,打印出下一个可用的员工标识码来展示静态方法。
 

// 文件StaticTest.java


public class StaticTest {
    public static void main(String[] args) {
        System.out.println("1111");
        Employee[] staff = new Employee[3];
        staff[0] = new Employee("Tom", 40000);
        staff[1] = new Employee("Dick", 60000);
        staff[2] = new Employee("Harry", 65000);

        for (Employee e: staff) {
            e.setId();
            System.out.println("name=" + e.getName() + ", id=" + e.getId() + ", salary=" + e.getSalary());
        }

        int n = Employee.getNextId();
        System.out.println("Next available id=" + n);
    }
}


class Employee {
    // 静态字段nextId
    private static int nextId = 1;
    private String name;
    private double salary;
    private int id;

    // 构造器
    public Employee(String n, double s) {
        name = n;
        salary = s;
        id = 0;
    }

    public String getName() {
        return name;
    }

    public  double getSalary() {
        return salary;
    }

    public int getId() {
        return id;
    }

    public void setId() {
        id = nextId;
        nextId++;
    }

    // 设置静态方法,静态方法中能调用静态字段
    public static int getNextId() {
        return nextId;
    }

    public static void main(String[] args) {
        Employee e = new Employee("Harry", 5000);
        System.out.println(e.getName() + " " + e.getSalary());
    }
}

  这里我们定义了2个类StaticTestEmployee,这两个类分别有一个main函数
  执行命令以下命令

java Employee

  结果如下:

Harry 5000.0

  当我们执行

java StaticTest

  结果如下:

name=Tom, id=1, salary=40000.0
name=Dick, id=2, salary=60000.0
name=Harry, id=3, salary=65000.0
Next available id=4

  两者会分别执行各自的main方法

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/164788.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 如何删除sqlserver实例_sql server删除表

    如何删除sqlserver实例_sql server删除表在网上找到下面几种方法,本人使用的是第一种,很实用。1.删除SQLServer的特定实例若要删除SQLServer的某个特定实例,请按照以下步骤操作:找到并删除%drive%:\\ProgramFiles\\MicrosoftSQLServer\\MSSQL\\Binn文件夹,其中%drive%是要删除的SQLServer实例的位置。找到以下注册表项:HKEY…

    2022年10月2日
    0
  • python中dtype什么意思_NumPy Python中的数据类型对象(dtype)

    python中dtype什么意思_NumPy Python中的数据类型对象(dtype)每个ndarray都有一个关联的数据类型(dtype)对象。此数据类型对象(dtype)告知我们有关数组布局的信息。这意味着它为我们提供了有关以下信息:数据类型(整数,浮点数,Python对象等)数据大小(字节数)数据的字节顺序(小端或大端)ndarray的值存储在缓冲区中,可以将其视为内存字节的连续块。因此,如何解释这些字节由dtype对象给出。1,构造数据类型(dtype)对象:数据类型对象…

    2022年6月5日
    101
  • 比较文本相似度_比较文本差异的工具

    比较文本相似度_比较文本差异的工具from:https://cloud.tencent.com/developer/news/218062本文作者为YvesPeirsman,是NLP领域的专家。在这篇博文中,作者比较了各种计算句子相似度的方法,并了解它们是如何操作的。词嵌入(wordembeddings)已经在自然语言处理领域广泛使用,它可以让我们轻易地计算两个词语之间的语义相似性,或者找出与目标词语最相似的词语。然而…

    2025年6月23日
    0
  • linux配置ntp时间同步客户端(小红帽系统怎么关闭程序)

    NTP网络时间服务器在LINUX系统设置方法(小红帽版)NTP网络时间服务器在LINUX系统设置方法(小红帽版)第一种方法:1.Linux系统使用命令行配置:在Linux上面执行ntpdate:ntpdate1Array2.168.0.1#1Array2.168.0.1是NTP服务器的IP2.使用hwclock命令,把时间写入bioshwclock-w如果想定时进行时间校准,可以使用crond服务来定时执行。编辑/etc/crontab文件加入下面一行:308**

    2022年4月10日
    74
  • php jquery教程下载,jquery 怎么下载

    php jquery教程下载,jquery 怎么下载下载jquery的方法:首先使用百度搜索“jQuery”;然后点击进入jQuery网站;最后找到适合开发的版本后进行下载即可。本教程操作环境:windows7系统、jquery3.2.1版,该方法适用于所有品牌电脑。下载jquery的方法:首先,打开您的浏览器,无论是什么浏览器都可以,只要可以连接上网络就行。使用百度搜索“jQuery”.您可以选择下图所示量项中的一项,并点击进入jQuery网站。…

    2022年5月4日
    26
  • mybatis的常用动态sql标签

    mybatis的常用动态sql标签一.定义sql语句select标签属性介绍:id:唯一的标识符.parameterType:传给此语句的参数的全路径名或别名例:com.test.poso.User或userresultType:语句返回值类型或别名。注意,如果是集合,那么这里填写的是集合的泛型,而不是集合本身(resultType与resultMap不能并用)<selectid=…

    2022年6月23日
    144

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号