前言

static关键字算是Java中比较复杂的关键字之一,它可以修饰变量、方法、类以及代码块。下面将介绍static的具体使用。并且扩展介绍关于程序入口函数public static void main(String[] args)的一些知识。

引入static的目的

在《Java编程思想》中对static的描述有这样的一句话:

static方法就是没有this的方法。在static的方法内部不能调用非静态方法,反过来到是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。

这最后一句便是引入static主要的用途,免去创建类对象的开销就可以调用类中的方法,可以说是十分诱人。

static的作用

Static修饰变量

private static int num;

变量num可以称为静态变量也可以称为类变量。

static修饰属性只能修饰类属性,不可以修饰局部变量,如方法中的定义的属性。Java中规定如此。

Java中的static和C++中的static含义是不一样的,C++中的static修饰的变量是全局变量,而Java中没有全局变量的概念,在Java中使用static修饰的类属性是存放在方法区的,为该类所有对象共享的变量,与具体某个对象没有关系

static属性和非static属性的区别主要有两点:①在内存区域的保存位置不同,static属性存放在方法区,非static属性存放在堆栈区。②static属性是属于类对象的公共属性,可以在没有实例化对象的前提下使用类名.静态属性名的方式访问;而非static属性则需要使用对象进行访问。

关于什么时候该使用static属性?

需要进行描述共享信息的属性并且该属性不需要重复开辟内存空间而且便于修改,则使用static进行修饰该变量。其余情况,不建议使用static修饰变量。

static修饰方法

public static void printNumberOfStudent(){
...
}

被static修饰的方法叫做静态方法。静态方法同静态变量一样可以直接使用类名称.静态方法名调用。若是使用类名调用静态方法需要满足该方法不是private。在非静态方法中是可以使用this访问静态变量。

在使用静态方法时需要注意两点:

  • 静态方法中是不存在this的。因为this是指向当前对象的,静态方法是与类相关的,与对象无关,不存在对象调用问题。一般直接使用类名.静态方法名 进行访问

  • 静态方法内部只能直接调用静态方法和静态成员。调用普通方法会报错,在普通方法中可以调用静态方法。

    因为普通方法一般会将对象作为隐藏实参传入并用this指向,在没有创建对象时,普通方法中就不存在this,调用包含普通方法的静态方法就会报错!

static修饰代码块

在程序编写中可以直接使用{...}定义一段语句块,这个语句块就是代码块,使用static修饰的语句块就叫做静态代码块。

观察下面程序的结果,分析静态块在程序中的执行顺序

public class A {
A(){
System.out.println("A constructor");
}
static {
System.out.println("A's static block");
}
}
public class B extends A{
B(){
System.out.println("B constructor");
}
static {
System.out.println("B's static block");
}
} public class StaticBlock {
public static void main(String[] args) {
B objb = new B();
}
} /*output
A's static block
B's static block
A constructor
B constructor
*/

可以看出静态代码块的执行顺序优先于构造函数,在程序执行时,会先找到main入口,然后准备加载类B,发现B有父类A,于是先去加载A,静态代码块就是在类加载的时候执行的。在静态块执行完后,就会去执行构造函数。

静态块因为在构造函数之前执行,所以常用来初始化静态变量

public  class Student {
private static int numOfStu;
private String name;
private int age; static {
numOfStu = 0;
} public Student(String name, int age) {
this.name = name;
this.age = age;
numOfStu++;
}
}

静态代码块可以在类的任意位置定义(方法中不可以),不会影响其优先于构造函数执行的顺序。但是多个静态块的执行顺序会依据其声明的前后执行。

public  class Student {
private static int numOfStu;
private String name;
private int age; static {
numOfStu = 0;
System.out.println("first sttaic block");
} public Student(String name, int age) {
this.name = name;
this.age = age;
numOfStu++;
} static {
System.out.println("second sttaic block");
} public static void main(String[] args) {
Student stu1 = new Student("sakura",20);
}
}
/*
output:
first sttaic block
second sttaic block
*/

static修饰内部类

内部类顾名思义就是定义在一个类中的类。使用static定义的属性或者方法是不受类实例化对象的控制的,所以,如果内部类被static修饰,是不会受到外部类实例化对象控制。此时,内部类就相等于变成了一个外部类,并且只能访问外部类中的static属性或者方法。关于内部类,后面会详细介绍。

public static void main(String[] args)

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

public static void main(String[] args)作为Java程序的入口方法,Java虚拟机在运行程序时,会首先查找main()方法。该方法中各个修饰符的作用如下:

  • 【public】: public 作为权限修饰符,表明任何类或者对象都可以访问这个方法。主方法是程序的开始,所以这个方法对任何操作都应该是可见。
  • 【static】: static表明main()方法是一个静态方法,即方法中的代码是存储在静态存储区的,当类被加载后,就可以直接使用类名来调用(在命令行使用java Test是调用Test.main主方法)。如此看被static修饰的主函数,这样的好处可能就是:不用创建当前类的对象就可以调用,节省空间。
  • 【void】: 主方法是一切执行的开始点,既然是起点,那么就没有回到其他方法中的返回值
  • 【String[] args】: 传递给程序的参数。输入的参数以空格隔开,若是输入的参数本省有空格,则使用双引号将该参数括起来。字符串参数args为开发人员在命令行状态下与程序交互提供了一种手段。

扩展一: main()方法是否还有其他可用的定义格式?

  1. 由于public和static没有先后顺序关系,所以下面的定义也是合理的

    static public void main(String[] args)
  2. 也可以将main()方法定义为final的

    public static  final void main(String[] args)
  3. 也可以使用synchronized关键字来修饰

    static public synchronized void main(String[] args)

但是不管使用哪种方式定义,都需要保证main()方法的返回值为void,并且有static和public关键字修饰。因为main()方法作为程序的入口,因此不能使用abstract关键字来修饰

扩展二: 同一个.java文件中是否可以有多个main()方法?

虽然每个类中都可以定义main()方法,但是只有与文件名相同的用public修饰的类中的main()方法才能作为整个程序的入口方法。如下所示:创建一个名为Test.java的文件

class T{
public static void main(String[] args){
System.out.println("T main");
}
}
public class Test{
// 程序入口函数
public static void main(String[] args){
System.out.println("Test main");
}
}
/*
output:
Test main
*/

小结

介绍了Java中static关键字的基础应用:修饰变量、方法等。Java中还可以利用static关键字实现单例模式,这些后面介绍。

参考:《Java编程思想》第四版

Java——static关键字的更多相关文章

  1. Java Static关键字详解

    提起static关键字,相信大家绝对不会陌生,但是,想要完全说明白,猛的一想,发现自己好像又说不太明白... ...比方说,昨天被一个同学问起的时候... ... 当然,不是所有人都像我一样学艺不精的 ...

  2. java static关键字

    方便在没有创建对象的情况下来进行调用(方法/变量). 很显然,被static关键字修饰的方法或者变量不需要依赖于对象来进行访问,只要类被加载了,就可以通过类名去进行访问. static可以用来修饰类的 ...

  3. Java static 关键字详解

    引言 在<Java编程思想>中有这样一段话:static方法就是没有this的方法.在static方法内部不能调用非静态方法,反过来是可以的.而且可以在没有创建任何对象的前提下,仅仅通过类 ...

  4. 【转载】java static 关键字的四种用法

    原文链接点这里,感谢博主分享 在java的关键字中,static和final是两个我们必须掌握的关键字.不同于其他关键字,他们都有多种用法,而且在一定环境下使用,可以提高程序的运行性能,优化程序的结构 ...

  5. [java]static关键字的四种用法

    在java的关键字中,static和final是两个我们必须掌握的关键字.不同于其他关键字,他们都有多种用法,而且在一定环境下使用,可以提高程序的运行性能,优化程序的结构.下面我们先来了解一下stat ...

  6. Java——static关键字---18.09.27

    static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但在Java语言中没有全局变量的概念. static关键字主要有两种作用: 一.为某特定数据类 ...

  7. Java static关键字的重新思考

    上完Java课,虽然也写了不少的Java代码,但是一直有不少的疑惑,而static关键字一直困惑着我很久,今天无意探究竟,上知乎再仔细查了一下,发现了这个话题的优秀答案https://www.zhih ...

  8. java static关键字和代码块

    static关键字 代码块 方法重写 1. 方法重写的特点: 2. 注意事项: static关键字 为什么需要学习static关键字? 针对某一个变量属于类而不属于某一个具体的对象的时候,我们可以考虑 ...

  9. java static关键字的使用

    static关键字    通常来说,创建类的时候,是用new创建此类的对象才可以获得,执行new创建对象时数据存储空间才被分配,其方法才被外界调用    有两种情况用new无法解决:        1 ...

随机推荐

  1. 20155205 郝博雅 Exp4 恶意代码分析

    20155205 郝博雅 Exp4 恶意代码分析 一.实验目标 1.监控你自己系统的运行状态,看有没有可疑的程序在运行. 2.分析一个恶意软件,就分析Exp2或Exp3中生成后门软件:分析工具尽量使用 ...

  2. OpenCV3.30 画图函数

    画图函数(Draw Functions)都放在imgpro. 例如C++中用: #include <opencv2\imgproc.hpp>

  3. Python爬虫的学习经历

    在准备学习人工智能之前呢,我看了一下大体的学习纲领.发现排在前面的是PYTHON的基础知识和爬虫相关的知识,再者就是相关的数学算法与金融分析.不过想来也是,如果想进行大量的数据运算与分析,宏大的基础数 ...

  4. MFC图片操作

    根据MFC要操作图片的来源,可分为以下两类: 一.非动态显示图片(即图片先通过资源管理器载入,有一个固定ID) 二.动态载入图片(即只需要在程序中指定图片的路径即可载入) 一.非动态显示图片 1.传送 ...

  5. 浅析http缓存

    1.什么是缓存 将服务器上的静态资源,保存在本地,当发送web请求的时候,如果本地有“已缓存”的静态资源,则从使用本地保存的静态资源,而不是从源原服务器再次请求. 2.缓存的优点 缓存减少冗余的数据传 ...

  6. Django搭建博客记(一)

    这里记录一些 Django 搭建博客遇到的一些问题 参考书籍为 Django by Example, 这里记录与书籍内容不包含的内容. 搭建环境: 阿里云 ECS + CentOS7 一开始搭建的时候 ...

  7. 关于浏览器跨域的一种实现--jsonp

    最近一直在搞python,前端技术荒废很久了,今天跟前端联调,设计到一个前端跨域的问题:前端人员告诉我可以用jsonp的方式实现,经他这么一提醒,也是豁然开朗. jsonp的实现方式我按照我的理解说一 ...

  8. CentOS 7 - 更新JDK,删除旧JDK,安装新JDK

    一,检查是否安装JDK. yum list installed | grep java 二,删除旧JDK. yum -y remove java-1.7.0-openjdk* yum -y remov ...

  9. FFmpeg开发实战(二):FFmpeg 文件操作

    FFmpeg 提供了丰富的API供我们使用,下面我们来讲述一下文件操作相关的API: FFmpeg 删除文件:avpriv_io_delete() FFmpeg 重命名文件:avpriv_io_mov ...

  10. 音视频编解码——LAME

    一.LAME简介 LAME是目前非常优秀的一种MP3编码引擎,在业界,转码成Mp3格式的音频文件时,最常用的就是LAME库.当达到320Kbit/s时,LAME编码出来的音频质量几乎可以和CD的音质相 ...