一、 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. [深度学习] pytorch学习笔记(3)(visdom可视化、正则化、动量、学习率衰减、BN)

    一.visdom可视化工具 安装:pip install visdom 启动:命令行直接运行visdom 打开WEB:在浏览器使用http://localhost:8097打开visdom界面 二.使 ...

  2. Zabbix连接

    下载: wget https://fossies.org/linux/misc/zabbix-4.0.5.tar.gz 安装: https://www.cnblogs.com/sunbeidan/p/ ...

  3. OPTS参数设置

    今天再hive on tez 跑任务的时候 OOM异常 然后找了些 JAVA OPTS设置: AVA_OPTS ,顾名思义,是用来设置JVM相关运行参数的变量. JVM:JAVA_OPTS=" ...

  4. [CSP-S模拟测试]:最小值(DP+乱搞)

    题目背景 $Maxtir$更喜欢序列的最小值. 题目传送门(内部题128) 输入格式 第一行输入一个正整数$n$和四个整数$A,B,C,D$. 第二行输入$n$个整数,第$i$个数表示$a_i$. 输 ...

  5. [CSP-S模拟测试]:陶陶摘苹果(线段树维护单调栈)

    题目传送门(内部题116) 输入格式 第一行两个整数$n,m$,如题 第二行有$n$个整数表示$h_1-h_n(1\leqslant h_i\leqslant 10^9)$ 接下来有$m$行,每行两个 ...

  6. RESTful API Design

    https://restful-api-design.readthedocs.org/en/latest/scope.html http://blog.mashape.com/30-ways-to-m ...

  7. Spring boot之返回json数据

    1.步骤: 1. 编写实体类Demo 2. 编写getDemo()方法 3. 测试 2.项目构建 编写实体类Demo package com.kfit; /** * 这是一个测试实体类. */ pub ...

  8. is == 编码与解码

    is 和 ==  主要是数字和字符串的比较 1 区别: ==比较的是两边的值     is比较的是两边值的id    id获取的方法 id() 2 小数据池: -5~256 3 字符串中特殊字符有id ...

  9. 第十三周Java课程学习总结

    学习总结: 记事本界面: 监听适配器. 可以通过Window Adapter来实现监听. void windowActivated(WindowEvent e) 激活窗口时调用. void windo ...

  10. Django admin 设置和定制

    models 在 models.py 中定义,每个 model 是一个 class: from django.db import models class PerformanceData(models ...