谈一谈Java中的“静态”
首先,我们需要用到我在博客:面向对象的内存分析 用到的一张关键的分析图
一、静态方法
1.静态方法与非静态方法的区别
我们首先看一看一个普通的类的调用:
public class Song {String title;public Song(String title) {this.title = title;}public void play(){SoundPlayer player = new SoundPlayer();player.playSound(title);}
}
很显然,一般情况下,我们调用另一个类,首先就要创建这个类的实例,然后以此调用类的方法。但是 事实上,Java有一些方法如实用方法(如Math),则不需要类的实例!而Java中,static这个关键词,可以标记出不需要实例的方法。这就是staic的作用。而static修饰的方法或者是变量就叫做静态方法或是静态变量。
我们可以系一行代码作为示例,看一下Math如果被实例化会出现什么情况:
错误提示:Math的构造函数被标记为私有的,因此,我们在使用Math类中的方法时,无法对其进行实例化我们可以去看一下它的部分源码:
public final class Math {/*** Don't let anyone instantiate this class.*/private Math() {}/*** The {@code double} value that is closer than any other to* <i>e</i>, the base of the natural logarithms.*/public static final double E = 2.7182818284590452354;/*** The {@code double} value that is closer than any other to* <i>pi</i>, the ratio of the circumference of a circle to its* diameter.*/public static final double PI = 3.14159265358979323846;
所以说,我们无需对Math进行实例化,用到的只有它的类的本身。对于Math类中的方法,都是被static修饰的方法,这些方法我们称之为静态方法。也很容易看到,静态方法中不存在对象的实例化,而是对类名字的直接引用。
是不是所有的类只要拥有一个或者是多个静态方法的类就不能被初始化?
当然不是!我们知道main()方法本身就是静态的方法,只要有main的方法的类就算有静态方法的类,但是我们同样可以在这个类中对其他类进行实例化,因此我们可以在类中任意组合静态与非静态的方法,然而任何非静态的方法都必须一实例化来操作。取得对象的方法只有new()或者序列化
2.静态方法不能调用非静态的变量或方法
通过上文,我们清楚了:静态方法是通过类名称来调用的,所以说静态的方法无法引用到该类的任何实例变量。示例如下:
编译器告诉我们:我不知道你说的是哪个实例变量! 也就是说静态方法是不知道堆上有哪些实例的。
那调用方法呢?同样是不被允许的!
静态方法无法看到实例变量的状态!
二、静态变量
1.静态变量的初始化
静态变量是在类的任何对象创建之前就完成初始化。
静态变量会在该类的任何静态方法执行之前就初始化。
静态变量不赋值时,默认初始化为0;
class Player {static int playerCount = 0;private String name;public Player(String name){this.name=name;playerCount++;}
}
public class PlayerTestDrive{public static void main(String[] args) {System.out.println(Player.playerCount);Player player = new Player("Tiger Woods");System.out.println(Player.playerCount);}
}
输出:
2.静态变量的作用
如果我们需要计算一个对象被实例化建立出来的次数?我们是不是可以利用构造函数进行累加计算?
public class Duck {int duckCount;public Duck() {duckCount++;}
}
显然这是不行的,因为duckCount是一个实例变量,所以这样做是不会成功的。每个Duck在被初始化的时候,duckCount的值都是0;这里我们有一种简单的方法,就是用static去修饰,这就是静态变量作用:被同类所有实例共享的变量
public class Duck {private int size;//静态的duckCount只会在第一次载入时被初始化private static int duckCount = 0;//当构造函数被执行,duckCount就会递增public Duck(){duckCount++;}public void setSize(int s){size=s;}public int getSize(){return size;}public static void main(String[] args) {Duck duck = new Duck();//每个Duck对象都有自己的size变量,但是所有的Duck实例只有一份duckCount变量duck.setSize(2);System.out.println("duckCount: "+duckCount+" duckSize: "+duck.getSize());duck.setSize(3);System.out.println("duckCount: "+duckCount+" duckSize: "+duck.getSize());//每创建一次对象就会重新载入构造函数,duckCount就会递增Duck duck1 = new Duck();System.out.println("duckCount: "+duckCount);}
}
输出:
1.静态变量在内存中只有一份拷贝,JVM只为其分配一次内存
2.对于实例变量,每创建一个实例,就会为实例变量分配一次内存,实例变量可以在内存中有多个拷贝,互不影响
3.静态变量是共享的,同一类所有的实例共享一份静态变量。如果不写递增方法,所有被实例的对象的duckCount都是0;
4.实例变量每个实例一个;静态变量每个类一个;
三、final变量
一个被标记final的变量代表该变量一旦被初始化就不会改动,也就是说类加载之后的静态final就不会再改变,因此,在使用final修饰变量时,变量必须被初始化,不然会报错。
1.final的初始化
(1)声明的时候:(final声明变量时,一般变量名要大写)
public class testFinal {private static final double COUNT=10;
}
(2)在静态初始化程序中:
public class testFinal {private static final double COUNT;static {COUNT = (double) Math.random();}
}
2.final其他用法
fina也可以修饰非静态变量,同样地,代表该值不能改变
final也可以修饰方法,代表该方法不能被覆盖掉
final也可以修饰类,代表该类不能被继承
四、静态的import
这种方法只能减轻少数代码量,同时也会增加代码的阅读难度,一般情况下不推荐使用
常规:
import java.lang.Math;
public class testImport {public static void main(String[] args){System.out.println("sqrt"+Math.sqrt(2.56));System.out.println("tan"+Math.tan(60));}
}
静态import
import static java.lang.Math.*;
import static java.lang.System.out;
public class testImport {public static void main(String[] args){out.println("sqrt"+sqrt(2.56));out.println("tan"+tan(60));}
}
事实上第二分段代码敲得更多些,说是节省代码量,仅仅是多次重读调用该包的时候
谈一谈Java中的“静态”相关推荐
- 非静态方法可以访问Java中的静态变量/方法吗?
"非静态方法可以访问静态变量或调用静态方法"是Java中有关静态修饰符的常见问题之一,答案是, 是的 ,非静态方法可以访问静态变量或调用静态方法. Java中的方法. 这没有问题, ...
- java中的静态是什么?怎么用?
Java属于入门容易,天花板却极高的编程语言.java中的静态是什么?对于java工程师来说技术的不断发展,需要不断学习java进阶知识.为了帮助大家巩固基础,本文解答了java中的静态是什么?怎么用 ...
- java中的静态、动态代理模式以及Spring中的CgLib动态代理解读(面试必问)
java中的静态.动态代理模式以及Spring中的CgLib动态代理解读(面试必问) 静态代理 动态代理 CgLib动态代理 基础知: 反射知识 代理(Proxy)是一种设计模式,提供了对目标 ...
- java 中的静态变量,静态代码块,动态代码块,构造方法执行顺序的深入探究
要想完全弄懂这个执行顺序,需要我们先了解几个概念. 首先是类加载与对象的构造,类加载就是在第一次调用这个类的时候jvm虚拟机会通过类加载器在一个叫做方法区的逻辑内存中将所要用到的类的信息存放在里边,其 ...
- java 静态变量方法,java中的静态变量和静态方法
java中的静态变量和静态方法 发布时间:2020-06-25 20:15:28 来源:亿速云 阅读:100 作者:Leah 今天就跟大家聊聊有关java中的静态变量和静态方法,可能很多人都不太了解, ...
- java javascript数组_浅谈javascript和java中的数组
javascript中的数组 数组的创建 直接创建方式 var str = ['java', 'js']; 使用new创建方式: var a = new Array(10); // 定义长度为1 ...
- 一语点破 Java 中的静态 static 关键字
来源 | blog.csdn.net/ju_362204801/article/details/90738966 思考:大家有没有想过一个问题,静态它为什么叫静态?因为书上或者别的文章里这么写的都这么 ...
- 一语点破Java中的静态static关键字
作者:嗑嗑磕嗑瓜子的猫 blog.csdn.net/ju_362204801/article/details/90738966 思考:大家有没有想过一个问题,静态它为什么叫静态?因为书上或者别的文章里 ...
- java 中的静态(static)代码块
类字面常量 final 静态域不会触发类的初始化操作 非 final static 静态域(以及构造器其实是一种隐式的静态方法) Class.forName():会自动的初始化: 使用 .class来 ...
最新文章
- mysql min函数 结果全为null_MySQL ----- 聚集函数(AVG,SUM,COUNT,MIN,MAX) (十一)
- 100G 最新技术学习资料大全分享 (2020 年最新)
- lamp wordpress
- 13.5 常见Random类
- Python的单引号、双引号和三引号的字符串
- 吴穹博士谈软件工程未来发展趋势
- 浅谈PopupWindow弹出菜单
- Java面试常考的面试题整理
- 荣耀20青春版能升鸿蒙吗,荣耀20青春版上手 配置跑分如何
- apb外设怎么分配地址
- Android Cloud to Device Messaging 服务介绍 – 如何使用云计算推送消息到手机(转载)...
- gg修改器怎么能让服务器检测不到,gg修改器怎么绕过检测 | 手游网游页游攻略大全...
- 云真机可以帮助测试解决什么问题?
- 聚合广告SDK开发(一)——基础知识
- Python实现PU口袋活动更新提醒
- multisimbcd码_8421BCD码加法器报告1
- 计算机维护费可以跨年吗,税控技术维护费跨年可以抵扣吗_增值税
- 地毯店人员告诉你如何正确选购合适地毯
- 基于51单片机的简易数字电压表proteus仿真原理图程序设计
- Matlab plotyy画双纵坐标图实例