今天学习的时候不太理解怎么使用静态函数,下面是查阅一些资料之后自己的理解
什么时候用静态函数
场景一
需要频繁使用的不变的函数
我们先来看一段代码
public class Test {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
//非静态函数
public void show(){
System.out.println("我是show");
}
//静态函数
public static void staticShow(){
System.out.println("我是静态函数");
}
}
public static void main(String[] args) {
//需要实例化test才能调用show函数
Test test = new Test();
test.show();
//不需要实例化就能通过类直接调用staticShow
Test.staticShow();
}
最后输出:
我是show
我是静态函数
可以直接看到静态函数和非静态函数的区别就是:静态函数不需要实例化对象就可以调用,而非静态函数需要一个实例化对象才能调用。
接着看下面这段代码
public class Test {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void show(){
System.out.println("我是"+ name);
}
public static void staticShow(){
System.out.println("我是静态函数");
}
public static void main(String[] args) {
//需要实例化test才能调用show函数
Test test = new Test();
test.setName("cr");
test.show();
//不需要实例化就能通过类直接调用staticShow
Test.staticShow();
}
}
输出:
我是cr
我是静态函数
如果要调用show,则需要传一个name,不是一个固定不变的量,所以我们不用静态函数。而staticShow中没有任何变量,所以可以使用静态函数。
场景二
隐藏函数
同时编译多个文件时,static函数没有全局可见性。
什么时候不建议使用态函数
多线程场景中函数依赖于具体的对象时。
举个例子:
public class Test {
static class trr{
static String name = "cr";
//修改name
static void move(String newName){
name = newName;
}
}
public static void main(String[] args) {
for (int i = 0; i < 6;i++){
new Thread(()->{
trr.move(Thread.currentThread().getName());
System.out.println(Thread.currentThread().getName() + "->" + trr.name);
}).start();
}
}
}
运行结果:
此时传入的参数和传出的参数不一定,说明线程不安全。
那么为了避免这种情况发生,就可以使用实例化方法
public class Test {
String name = "cr";
//修改name
void move(String newName){
name = newName;
}
public static void main(String[] args) {
Test test = new Test();
for (int i = 0; i < 16;i++){
new Thread(()->{
test.move(Thread.currentThread().getName());
System.out.println(Thread.currentThread().getName() + "->" + test.name);
}).start();
}
}
}
运行结果:
使用实例化方法就不会发生上面的情况了
那么如果非要在多线程场景下用静态函数,那可以加锁
public class Test {
static class trr{
static String name = "cr";
//修改name
static void move(String newName){
name = newName;
}
}
public static void main(String[] args) {
for (int i = 0; i < 16;i++){
new Thread(()->{
//加锁
synchronized (trr.class) {
trr.move(Thread.currentThread().getName());
System.out.println(Thread.currentThread().getName() + "->" + trr.name);
}
}).start();
}
}
}
运行结果: