【java】Static解读和public static void main(String[] args)详细分析

2023-10-30

首先问一个问题:

public static void main(String[] args)代码代表了什么含义?以及思考为什么java程序一开始就会进入main()函数,其实c、c++也是如此?后面一个问题有static的基础就非常容易。(后一个问题的答案提前公布:用static修饰的代码块表示静态代码块,当Java虚拟机(JVM)加载类时,就会执行该代码块)

  现在回到第一个问题:

  下面分别解释这些关键字的作用:

(1)public关键字,这个好理解,声明主函数为public就是告诉其他的类可以访问这个函数。

(2)static关键字,告知编译器main函数是一个静态函数。也就是说main函数中的代码是存储在静态存储区的,即当定义了类以后这段代码就已经存在了。如果main()方法没有使用static修饰符,那么编译不会出错,但是如果你试图执行该程序将会报错,提示main()方法不存在。因为包含main()的类并没有实例化(即没有这个类的对象),所以其main()方法也不会存。而使用static修饰符则表示该方法是静态的,不需要实例化即可使用。

(3)void关键字表明main()的返回值是无类型。

(4)参数String[] args

  

public class Testargs {
    public static void main(String[] args) {
        String str = new String();
        for (int i = 0; i < args.length; i++) {
            System.out.println(args[i]);
            str += args[i];
        }
        System.out.println(str);
    }
}

     如果不使用编译器,使用命令行进行编译。你可以在准备编译class的时候传入abc,那么上面程序运行的结果就是abc,也就是参数args的主要作用是为程序使用者在命令行状态下与程序交互提供了一种手段。

     另外一种作用就是像正常函数方法一样调用其函数,但是需要注意的一点就是static声明的变量或者方法,是类方法或者说是类变量,不需要实例化就可以直接使用

具体实现步骤:

首先声明一个类A:

public classA {
  public static void main(String[] args)
  {
     for (int i = 0; i < args.length; i++) {
       System.out.println(args[i]);
     }
  }
}


接着再写一个B类:

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

  {
 
  //A c = new A();
 
  String[] b = {"111","222","333"};
 
  //c.main(b); //输出111 222 333
 
  //因为main()函数是静态函数,因此不需要实例化就可以使用
  A.main(b);//输出结果和上面的是一样的
 
  }
}
这个没有很常用,只是作为了解就可以了


static 修饰符能够与变量、方法一起使用,表示是“静态”的。


静态变量和静态方法能够通过类名来访问,不需要创建一个类的对象来访问该类的静态成员,所以static修饰的成员又称作类变量和类方法。静态变量与实例变量不同,实例变量总是通过对象来访问,因为它们的值在对象和对象之间有所不同。

请看下面的例子:

public class Demo {
    static int i = 10;
    int j;
    Demo() {
        this.j = 20;
    }
    public static void main(String[] args) {
        System.out.println("类变量 i=" + Demo.i);
        Demo obj = new Demo();
        System.out.println("实例变量 j=" + obj.j);
    }
}


运行结果:
类变量 i=10
实例变量 j=20

static 的内存分配

静态变量属于类,不属于任何独立的对象,所以无需创建类的实例就可以访问静态变量。之所以会产生这样的结果,是因为编译器只为整个类创建了一个静态变量的副本,也就是只分配一个内存空间,虽然有多个实例,但这些实例共享该内存。实例变量则不同,每创建一个对象,都会分配一次内存空间,不同变量的内存相互独立,互不影响,改变 a 对象的实例变量不会影响 b 对象。

请看下面的代码:

    
    
  1. public class Demo {
  2. static int i;
  3. int j;
  4. public static void main(String[] args) {
  5. Demo obj1 = new Demo();
  6. obj1.i = 10;
  7. obj1.j = 20;
  8. Demo obj2 = new Demo();
  9. System.out.println("obj1.i=" + obj1.i + ", obj1.j=" + obj1.j);
  10. System.out.println("obj2.i=" + obj2.i + ", obj2.j=" + obj2.j);
  11. }
  12. }
运行结果:
obj1.i=10, obj1.j=20
obj2.i=10, obj2.j=0

注意:静态变量虽然也可以通过对象来访问,但是不被提倡,编译器也会产生警告。

上面的代码中,i 是静态变量,通过 obj1 改变 i 的值,会影响到 obj2;j 是实例变量,通过 obj1 改变 j 的值,不会影响到 obj2。这是因为 obj1.i 和 obj2.i 指向同一个内存空间,而 obj1.j 和 obj2.j 指向不同的内存空间,请看下图:

图1  静态变量内存分配

注意:static 的变量是在类装载的时候就会被初始化。也就是说,只要类被装载,不管你是否使用了这个static 变量,它都会被初始化。

小结:类变量(class variables)用关键字 static 修饰,在类加载的时候,分配类变量的内存,以后再生成类的实例对象时,将共享这块内存(类变量),任何一个对象对类变量的修改,都会影响其它对象。外部有两种访问方式:通过对象来访问或通过类名来访问。

静态方法

静态方法是一种不能向对象实施操作的方法。例如,Math 类的 pow() 方法就是一个静态方法,语法为 Math.pow(x, a),用来计算 x 的 a 次幂,在使用时无需创建任何 Math 对象。

因为静态方法不能操作对象,所以不能在静态方法中访问实例变量,只能访问自身类的静态变量。

以下情形可以使用静态方法:
  • 一个方法不需要访问对象状态,其所需参数都是通过显式参数提供(例如 Math.pow())。
  • 一个方法只需要访问类的静态变量。

读者肯定注意到,main() 也是一个静态方法,不对任何对象进行操作。实际上,在程序启动时还没有任何对象,main() 方法是程序的入口,将被执行并创建程序所需的对象。

关于静态变量和静态方法的总结:

  • 一个类的静态方法只能访问静态变量;
  • 一个类的静态方法不能够直接调用非静态方法;
  • 如访问控制权限允许,静态变量和静态方法也可以通过对象来访问,但是不被推荐;
  • 静态方法中不存在当前对象,因而不能使用 this,当然也不能使用 super;
  • 静态方法不能被非静态方法覆盖;
  • 构造方法不允许声明为 static 的;
  • 局部变量不能使用static修饰。


静态方法举例:

    
    
  1. public class Demo {
  2. static int sum(int x, int y){
  3. return x + y;
  4. }
  5. public static void main(String[] args) {
  6. int sum = Demo.sum(10, 10);
  7. System.out.println("10+10=" + sum);
  8. }
  9. }
运行结果:
10+10=20

static 方法不需它所属的类的任何实例就会被调用,因此没有 this 值,不能访问实例变量,否则会引起编译错误。

注意:实例变量只能通过对象来访问,不能通过类访问。


关于在静态方法中间接调用非静态方法示例:

package com.imooc.testargs;

public class StaticInvokeNonStaticMethod {

	private String name;

	public StaticInvokeNonStaticMethod(String name) {
		this.name = name;
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		StaticInvokeNonStaticMethod s = new StaticInvokeNonStaticMethod(
				"zhangsan");
		StaticInvokeNonStaticMethod s2 = new StaticInvokeNonStaticMethod(
				"wangwu");
		StaticInvokeNonStaticMethod.ask(s);
		StaticInvokeNonStaticMethod.ask(s2);
		//s.ask(s2); // 对象调用静态方法的方式不推荐使用
	}

	/**
	 * 通过传入一个实例对象的方法引用,达到静态方法内部调用非静态方法
	 * */
	public static void ask(StaticInvokeNonStaticMethod s) {
		System.out.println("静态方法内部调用非静态方法");
		//System.out.println(s);  //这是在类中访问类对象,不是实例变量
		//Cannot make a static reference to the non-static field name, 说明不能在静态方法中访问实例变量
		//System.out.println(name);  
		
		s.say();   
	}

	public void say() {
		System.out.println("hello my name is " + name);
	}
}


静态初始器(静态块)

块是由大括号包围的一段代码。静态初始器(Static Initializer)是一个存在于类中、方法外面的静态块。静态初始器仅仅在类装载的时候(第一次使用类的时候)执行一次,往往用来初始化静态变量。

示例代码:

    
    
  1. public class Demo {
  2. public static int i;
  3. static{
  4. i = 10;
  5. System.out.println("Now in static block.");
  6. }
  7. public void test() {
  8. System.out.println("test method: i=" + i);
  9. }
  10. public static void main(String[] args) {
  11. System.out.println("Demo.i=" + Demo.i);
  12. new Demo().test();
  13. }
  14. }
运行结果是:
Now in static block.
Demo.i=10
test method: i=10

静态导入

静态导入是 Java 5 的新增特性,用来导入类的静态变量和静态方法。

一般我们导入类都这样写:

    
    
  1. import packageName.className; // 导入某个特定的类

    
    
  1. import packageName.*; // 导入包中的所有类

而静态导入可以这样写:

    
    
  1. import static packageName.className.methonName; // 导入某个特定的静态方法

    
    
  1. import static packageName.className.*; // 导入类中的所有静态成员

导入后,可以在当前类中直接用方法名调用静态方法,不必再用 className.methodName 来访问。

对于使用频繁的静态变量和静态方法,可以将其静态导入。静态导入的好处是可以简化一些操作,例如输出语句 System.out.println(); 中的 out 就是 System 类的静态变量,可以通过 import static java.lang.System.*; 将其导入,下次直接调用 out.println() 就可以了。

请看下面的代码:

    
    
  1. import static java.lang.System.*;
  2. import static java.lang.Math.random;
  3. public class Demo {
  4. public static void main(String[] args) {
  5. out.println("产生的一个随机数:" + random());
  6. }
  7. }
运行结果:
产生的一个随机数:0.05800891549018705

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【java】Static解读和public static void main(String[] args)详细分析 的相关文章

随机推荐

  • C ++ Primer(第五版)第十三章练习答案

    C Primer 第五版 第十三章练习答案 13 1 1 节练习 练习 13 1 练习 13 2 练习 13 3 练习 13 4 练习 13 5 13 1 2 节练习 练习 13 6 练习 13 7 练习 13 8 13 1 3 节练习 练
  • Dubbo与SpringCloud框架详解

    一 互联网架构演进 1 互联网项目架构 1 互联网项目与传统项目 互联网项目架构的特点 用户多 流量大 并发高 海量数据 易受攻击 功能繁琐 变更快 传统项目和互联网项目的不同 用户体验 美观 功能 速度 稳定性 大型互联网项目架构的目标
  • Qt/C++实现函数指针的使用

    1 背景 对于if else语句或者switch case语句非常累赘 且每个分支结构基本一致情况下 可以使用列表方式代替if else或者switch case 对于C语言这方面很容易实现 但是对于C 的类成员来说需要特殊的要求 2 代码
  • AVX Intrinsics各函数介绍

    SIMD相关头文件包括 include
  • 《Linux运维实战:Centos7.6一键离线部署mysql5.7.29集群》

    文章目录 一 部署背景 三 部署工具 三 部署演示 总结 整理不易 如果对你有帮助 可否点赞关注一下 一 部署背景 由于业务系统的特殊性 我们需要面向不通的客户安装我们的业务系统 而作为基础组件中的mysql针对不同的客户环境需要多次部署
  • Android 多选按钮Button

    一 先上效果图 二 准备阶段 资源文件 可根据项目需要调整样式 大小和颜色等 在res文件夹下创建以下资源文件 根据根标签选择Root Element 1 bg btn no select xml
  • 【数据对比】Parasoft Jtest如何提高Java测试ROI,加速软件交付!

    Parasoft Jtest通过提供一套工具来加速Java软件开发 以保证您的软件可靠 安全和可维护 从而最大限度地提高质量并最大限度地降低业务风险 经广泛证明 Parasoft Jtest是一个可以提高开发团队生产力和软件质量方法的集成解
  • 使用jvisualvm的jstatd方式远程监控Java程序

    使用Java自带的jvisualvm调试Java程序 可以查看CPU 内存 类及线程等信息 还可以进行Dump 无疑是一个利器 由于客户端是Windows 服务端是Linux 并且是最小安装的Linux 没有图形界面 因此需要进行远程调试
  • vue循环如何动态加载本地图片

    显示效果 代码 html
  • Excel中利用OFFSET函数解决很多个分块的一次性转置问题(非纯手动)

    今天遇到一个问题 需要将Excel中的一门课的平时成绩根据每个同学的作业次数进行转置排列 原始EXCEL表中内容如下 上表每个同学对应一个学号 该学号同学的作业和分数相应已知 现在为了统计方便 我要得到如下表的效果 因为学生人数众多 所有不
  • 【100%通过率 】【华为OD机试c++/java

    华为OD机试 题目列表 2023Q1 点这里 2023华为OD机试 刷题指南 点这里 题目描述 祖国西北部有一片大片荒地 其中零星的分布着一些湖泊 保护区 矿区 整体上常年光照良好 但是也有一些地区光照不太好 某电力公司希望在这里建设多个光
  • Qt动态库调用

    在开发过程中调用第三方的动态库应该是不可避免的 调用DLL的方式也不算少 可以通过Win32 API 直接调用 Qt的API等诸多方式进行调用 这里着重介绍一下Qt自带的API调用DLL的方法 以调用DLLTest dll中返回值为bool
  • phpstorm的一些方便开发的操作

    1 php的xdebug插件 方便调试 1 1首先要确定自己的php版本 通过phpinfo 来查看 在页面上查看phpinfo的信息 复制其源码页面的所有信息 1 2 到https xdebug org 获取插件 1 3点击以下链接进行p
  • *.ui界面文件对应的ui_*.h文件的作用

    研究 ui界面文件对应的ui h文件的作用 ui h 是在对 ui 文件编译后生成的一个文件 ui h 会出现在编译后的目录下 或与 ui 同目录 与项目的 shadow build 编译设置有关 查看 ui h 文件的内容 发现它主要做了
  • selenium报错解决

    selenium报错解决 报错原因如下 selenium common exceptions ElementNotvisibleException Message element not interactable session info
  • C-const与指针

    const int p 不可以对 p 再次进行赋值 但可以对p进行再次赋值 p 6 p int const p 不可以对p再次进行操作 但可以对 p 再次进行操作 p 6 p const int const p 既不可以对p再次进行操作 也
  • 面试八股文(c++)

    C 1 多态 虚函数 纯虚函数的作用 多态 一个东西有多种形式 不同的对象 在收到相同的信息时产生不同的行为 好处 1 应用程序不必为每个派生类编写功能调用 只需要对抽象基类进行处理即可 大大提高程序的可复用性 2 派生类的功能可以被基类的
  • ip 地址与mac 地址的理解。软件如何识别用户?如何欺骗软件?修改mac地址的方法。windows 10文件夹权限问题!

    当你看到这篇文章的题目时 也许会想 究竟其围绕的主题是什么 答案是 我也不知道 某些时候无题杂谈也许更符合现实意义 在我胡说八道之前请再允许我说一些废话哈 不想看的时候可以略过的 之前了解 TeamViewer 的破解工具 结果没有通过审核
  • 【北交所周报】北证指数周内涨幅一度超7%,刷新历史单日涨幅;力王股份上市首日涨超100%;北交所现开市以来首个自然人“举牌”...

    上周 9月4日 9月8日 北交所个股整体走强 六成个股上涨 北证指数上涨1 81 最高触及863 63点 最低报811 06点 9月8日收盘报817 02点 ITValue 上周 9月4日 9月8日 北证指数上涨1 81 最高触及863 6
  • 【java】Static解读和public static void main(String[] args)详细分析

    首先问一个问题 public static void main String args 代码代表了什么含义 以及思考为什么java程序一开始就会进入main 函数 其实c c 也是如此 后面一个问题有static的基础就非常容易 后一个问题