一、 static的用途

在Java编程思想中有这么一句话:“static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。这实际上正是static方法的主要用途”

这句话在我理解来说就相当于是static方法是属于类的,而非静态方法是属于对象的。在实际应用中就相当于非静态方法只有在new出相应的对象来才能调用,而静态方法只需要’类名.方法’即可调用。

在什么情况下我们需要使用static关键字呢?

a、 对于一个类相对固定的一些参数及方法

b、 一些需要预先定义的参数及方法

c、 一些调用广泛的公共参数及方法

在我看来static关键字的核心是避免一些内存的重复占用,我们想象一个java工程在开始运行时,会通过jvm分配一片空间,在这一片空间中会预先加载所有需要的类,然后就是我们在new对象时不停的占据内存。但是例如枚举类(之后称为Contact类)中的参数是会在其他很多对象和函数中调用,如果我们每次调用的时候都需要重新new一个Contact对象,岂不是会在内存中重复占用非常多的资源。这时我们就需要static关键字修饰Contact类中的参数,这样在我们预先加载所有的类时,Contact类中通过static修饰的参数就会随着Contact类一起被加载在内存中,在我们需要的时候就可以直接通过Contact.参数名来调用这个参数而不需要重复占用另外的内存。(如果在面试中刚好被问到了,答出来应该会很加分的)

1、 修饰类变量

static变量一般也被称为静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。

  static成员变量的初始化顺序按照定义的顺序进行初始化。

接下来举例说明:

这是一个基本的Man类,并生成了两个对象,但是从类的定义上来看,我们可以认为sex参数的值固定为男,但生成了两个对象就相当于在内存在将sex参数存储了两遍,这无疑是一种内存上的浪费。而这时我们给sex参数加上static关键字会变成什么样呢?

我们只需要给Man类中的sex参数赋值就会使所有的Man对象sex值进行改变。

虽然sex参数成为了Man类的共享属性,但是实际中我们很少这么使用,因为这样会使得该参数很难控制,因为它在任何地方都可能被改变。所以我们一般采用其他的使用方法:

通过private+static修饰count属性,并在Man的构造函数中对Man对象的数量进行统计并赋值给id属性来区分不同的Man对象。并且因为private修饰外界无法随意更改count和id参数。

2、 修饰类方法

与静态参数使用场景基本相同,但是需要注意的是,同一个类,静态方法中无法直接调用非静态参数及非静态方法,但非静态方法中可以直接调用静态方法及静态参数。

3、 静态代码块

静态代码块主要作用是在类加载之前进行一些数据的处理,对需要参数或对象的初始化。保证接下来对该参数或对象的使用。

这个例子就大致展现出了静态代码块的一些基本的作用,另外我们可以看看这个例子,展现了静态代码块和对象初始化时的加载顺序:

4、 静态导包

静态导包是一种比较少见是static使用方式,接下来使用一个例子来说明一下吧:

如图,当我们使用import static staticpkg.Man.*;时,在不与本类方法名冲突的前提下,我们可以在本类中直接使用Man类中的static方法,就像是本类自己的方法一样。但是相应的其他静态参数和一下非静态参数和非静态方法就无法直接调用了。

5、 静态内部类

首先简单描述一下什么是内部类,Java中是允许在类的构建中定义另一个类的,内部类有很多优点,首先就是不能被同一包的其他类所见,具有很好的封装性,其次还有就是内部类对象可以访问创建它的对象的实现,包括私有数据等;

还是举个例子说明一下:

输出结果为:

从例子中的注释我们可以看到内部类有许多的特性:

1、 静态内部类中可以存在静态成员,而非静态内部类中不能有静态成员。

2、 静态内部类可以访问外部类的静态成员,而非静态内部类则可以访问外部类的所有成员。

3、 如果需要在其他类中实例化本类中的非静态内部类,需要先修改非静态内部类的访问限制符,然后实例化外部类,再通过外部类对象实例化非静态内部类。

4、 如果需要在其他类中实例化本类中的静态内部类,需要先修改静态内部类的访问限制符,然后直接通过new 该静态内部类就可以了。

5、 调用静态内部类的静态成员时,可以通过外部类名.内部静态类名.静态参数名称或静态方法名。

二、 static作用分析

1、 之前说了static是跟随着类进行加载的,那么我们是否能通过this来进行静态参数的调用呢?

我们可以看到虽然静态参数是随着类进行加载的,但是在参数名有冲突的情况下依然可以通过this来进行参数调用,以此区分全局变量和局部变量的不同。

2、 static是跟跟随着类进行加载的,那么伴随着类、基础、对象的初始化过程中相应的加载顺序是怎样的?

举例1:

这两段代码的输出结果会是怎样的?

我们说了static是跟着类一起进行加载的,那么我们在new Test3()时会加载Test3类这时发现Test3继承Test2那么我们需要先加载Test2类的静态代码块,再加载Test3类的静态代码块。类加载完成后我们开始通过Test3提供的构造器来今天Test3对象的初始化,而因为Test3继承了Test2所以在编译时默认Test3的构造器中有一个super()的调用,意思就是先加载Test2的构造器再加载Test3的构造器。所以这两段的代码的输出结果如下:

举例2:

这三段代码的加载顺序又应该是怎样的呢?

首先和举例1一样main函数中加载Test3类,但是因为继承Test2所以先加载Test2类的静态代码块,然后是Test3的静态代码块,然后开始加载Test3的构造函数了,同样因为继承需要先加载Test2的构造函数,但是需要初始化Test2对象时需要将Test2类中的全局变量进行逐行加载,这时我们就需要加载new Test4(“test22222222”),这时就需要加载Test4类了,执行Test4类的静态代码块,然后执行Test4的构造器,Test4对象加载完成,进行Test2类的构造器加载,然后到了Test3类构造器加载,同上需要先加载Test4类,因为Test4类的静态代码块已经加载完成无需重复加载,所以加载Test4的构造器,然后加载Test3的构造器,所以这三段代码的输出结果应为:

举例3:

Main函数中明明什么都没写为什么还是会打印呢?

因为在加载main函数时,会先对Test5类进行逐行加载,这时会从上到下依次加载两个静态代码块,加载完成后,本类加载完成开始执行main函数中的代码,结果main函数中没有代码,程序结束。

以上是我对static的一些基本的认知,希望能对你有所帮助,代码依然是图片,代码还是手敲一遍试一下更有感觉的。

参考博客:

https://www.cnblogs.com/dotgua/p/6354151.html?utm_source=itdadao&utm_medium=referral

http://www.cnblogs.com/dolphin0520/p/3799052.html

https://www.cnblogs.com/aademeng/articles/6192954.html

Java static基本认知的更多相关文章

  1. Java static 的一两点使用

    这篇文章是关于Java static关键字的使用,主要会介绍以下的内容: static 的概念 static的各种应用 总结 static 是什么 static 顾名思义是静态的意思.与this相对, ...

  2. java static 变量,和方法从属于类

    第36集 java static 变量,和方法从属于类 可以用类来直接调用static属性和方法 static方法不能调用非静态的属性和方法,反之可以 new产生的对象,不包括static 属性和方法

  3. [转]java static final 初始化

    http://tanbing1986411.blog.163.com/blog/static/7259798220103610224434/ java static final 初始化 1.stati ...

  4. Java static修饰符

    Java static修饰符 static修饰符是静态修饰符,大家写Java第一次接触static就是主函数中的pubic static void main的声明了. 那么static有什么用?本文来 ...

  5. Java 调用Azure认知服务Demo--Computer API

    说明 本文主要介绍使用Java代码,基于HTTP请求调用Microsoft Azure的认知服务.图片来源分别介绍了使用公网的URL和上传本地图片. 依赖的jar包下载地址: key的获取需要登录到A ...

  6. Java Static关键字详解

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

  7. Java网络通信初步认知

    本文转载自:http://wing011203.cnblogs.com/ 在这篇文章里,我们主要讨论如何使用Java实现网络通信,包括TCP通信.UDP通信.多播以及NIO. TCP连接 TCP的基础 ...

  8. java static

    一. static代表着什么 在Java中并不存在全局变量的概念,但是我们可以通过static来实现一个“伪全局”的概念,在Java中static表示“全局”或者“静态”的意思,用来修饰成员变量和成员 ...

  9. Java static解析

    static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块 一.static变量 被static修饰的成员变量和成员方法独立于该类的任何对象.也就是说,它 ...

随机推荐

  1. fiddler https

    fiddler  里面的action 点选remove的那个   手机端清理凭据 在重新添加(在手机浏览器先输入代理的地址 下载证书 之后再安装)

  2. 在$scope中变量和方法的使用

    代码: angularjs.html <!doctype html> <html> <head> <meta charset="UTF-8" ...

  3. 在对 Angular 的文档 aio 进行编译的时候提示错误

    error angular-examples-master@1.0.0: The engine "yarn" is incompatible with this module. E ...

  4. C++入门经典-例3.1-判断输入的数字是否为奇数

    1:代码如下: // 3.1.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> using ...

  5. mysql 判断时间 语法

    今天  select * from 表名 where to_days(时间字段名) = to_days(now());  昨天  SELECT * FROM 表名 WHERE TO_DAYS( NOW ...

  6. maven国内镜像、国内外仓库(直接下载jar)

    阿里: https://maven.aliyun.com/mvn/search 官方: http://repo.maven.apache.org/maven2/ maven仓库 阿里巴巴的镜像仓库, ...

  7. java跨平台的原因

    java跨平台的原因 java有虚拟机(JVM),JAVA程序不是直接在电脑上运行的,是在虚拟机上进行的,每个系统平台都是有自己的虚拟机(JVM),所以JAVA语言能跨平台. 1.java代码不是直接 ...

  8. legend3---4、lavarel中session使用注意

    legend3---4.lavarel中session使用注意 一.总结 一句话总结: session('key',$value)不是存值,是设置默认值,session(['key'=>$val ...

  9. Java-Thread 线程

    一.进程与线程的概念 进程和线程都是一个CPU工作时间段的描述,只是关注点不同. 进程(Process): 资源(CPU,内存等,文件,网络等)分配的基本单位.系统中有很多进程,它们都会使用内存.为了 ...

  10. oracle delete 数据恢复

    /*1.FLASHBACK QUERY*/ --闪回到15分钟前 select *  from orders  as of timestamp (systimestamp - interval ''1 ...