static关键字的作用
来源:互联网 发布:制作视频片头软件 编辑:程序博客网 时间:2024/06/10 16:39
如果使用static定义属性,那么这个变量就被称为静态属性。那什么是静态属性呢?使用静态属性又有什么好处呢?
我们举一个例子:
1、静态属性和静态方法
package com.feiyu.myapplication;/** * Created by qianye on 2017/6/15. */class People { String name; String sex; public People(String name, String sex) { this.name = name; this.sex = sex; } public String show() { return "name = " + this.name + " sex = " + this.sex; }}public class Student { public static void main(String[] args) { People p1 = new People("盖伦", "男"); People p2 = new People("赵信", "男"); People p3 = new People("嘉文", "男"); System.out.println(p1.show()); System.out.println(p2.show()); System.out.println(p3.show()); }}
这样运行代码输出的结果必然是:
name = 盖伦 sex = 男name = 赵信 sex = 男name = 嘉文 sex = 男
那么如果我创建了100个对象,这100个对象全部是男性呢?我是不是要给每一个对象都设置一遍参数呢?
这样做实在太繁琐。这个时候我们就需要用到static关键字了。我们修改People类:
class People { String name; static String sex;//使用static修饰sex public People(String name, String sex) { this.name = name; this.sex = sex; } public String show() { return "name = " + this.name + " sex = " + this.sex; }}public class Student { public static void main(String[] args) { People p1 = new People("盖伦", "男"); People p2 = new People("赵信", "男"); People p3 = new People("嘉文", "男"); System.out.println(p1.show()); System.out.println(p2.show()); System.out.println(p3.show()); p1.sex = "女"; System.out.println("修改后"); System.out.println(p1.show()); System.out.println(p2.show()); System.out.println(p3.show()); }}
输出结果:
name = 盖伦 sex = 男name = 赵信 sex = 男name = 嘉文 sex = 男修改后name = 盖伦 sex = 女name = 赵信 sex = 女name = 嘉文 sex = 女
由此我们看出:
statci修饰的属性被类的所有对象所共享,我们可以称之为公共属性。
static修饰的属性也可以直接被类调用,比如 People.sex = “无性别”;
同样的,static也可以用来修饰方法,我们称之为静态方法,静态方法同样可以由类名称直接调用,也可以由对象调用。
java代码的主函数之所以写成public static是因为:1、java虚拟机要调用类的main方法,所以它必须是public的。2、虚拟机在执行main方法时不必创建对象,所以它必须是static的。
2、静态代码块:
一个类使用静态代码块,当这个类被加载的时候会首先执行静态代码块,并且只执行一次。静态代码块的执行要优先于静态方法,因此它可以对静态属性初始化。
我们可以做一个试验:
package com.feiyu.myapplication;class People { String name; static String sex; //静态代码块,如果不使用static修饰,此代码块就会在每次构建对象时执行。 static { System.out.println("静态代码块测试"); } public People(String name, String sex) { this.name = name; this.sex = sex; } public String show() { return "name = " + this.name + " sex = " + this.sex; } public static void setSex(String newSex) { sex = newSex; }}public class Student { public static void main(String[] args) { People p1 = new People("盖伦", "男"); People p2 = new People("赵信", "男"); People p3 = new People("嘉文", "男"); System.out.println(p1.show()); System.out.println(p2.show()); System.out.println(p3.show()); }}
输出结果:
静态代码块测试name = 盖伦 sex = 男name = 赵信 sex = 男name = 嘉文 sex = 男
以上就是static的基本介绍。
那么在android里使用static需要注意什么呢?
1、静态变量在类加载的时候就会分配内存
启动APP(或启动进程)的时候加载
2、静态变量在类被卸载的时候销毁
关闭APP(或销毁进程)的时候卸载
3、由于进程被杀死的时候静态变量也会销毁,所以不能保证静态变量一直存在。(想想这也是理所当然的吧(^__^) )
4、每次打开APP静态变量都会被赋予初始值,这就是为什么APP内部一些常量字符串,访问地址被设置成static的原因了。
5、使用static构建单例模式的时候,小心内存泄露:
比如我们写一个单例:
public class SingleManager { private Context context; private static SingleManager manager; public static SingleManager getInstance(Context context) { if (manager == null) manager = new SingleManager(context); return manager; } public SingleManager(Context context) { this.context = context; }}
然后我们在某一个activity里获取这个单例:
public class MainActivity extends AppCompatActivity { private SingleManager manager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //这里传入当前activity的context,会导致activity没法释放而造成内存泄露 manager = SingleManager.getInstance(this); }}
这就是一个典型的内存泄露。我们知道静态变量是和进程的生命周期相关的,当APP运行的时候这个静态变量会一直存在,那么它也就会一直持有MainActivity的引用,从而导致MainActivity无法释放而造成内存泄露。
那么应该怎么写单例呢?其实我们只要传入Application的contenxt就可以了。
如下:
public class SingleManager { private Context context; private static SingleManager manager; public static SingleManager getInstance(Context context) { if (manager == null) manager = new SingleManager(context); return manager; } public SingleManager(Context context) { //this.context = context; //使用Application的context this.context = context.getApplicationContext(); }}
另外一种不太明显看出来的内存泄露:
非静态内部类和匿名内部类持有外部类的引用造成的内存泄露。
如:
public class MainActivity extends AppCompatActivity { private SingleManager manager; // private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //这里传入当前activity的context,会导致activity没法释放而造成内存泄露 manager = SingleManager.getInstance(this); //延时10分钟发送一个消息 handler.postDelayed(new Runnable() { @Override public void run() { } }, 60 * 10 * 1000); finish(); }}
通过handler发送runable对象,当activity销毁以后,这个handler发送的消息仍然在消息队列中活着,直到10分钟以后被处理,然而这个handler对象会持有activity的引用导致acitivity不能被销毁从而造成内存泄露。
那么怎么解决呢?这个时候又要用到我们的static关键字了。我们可以定义一个静态内部类,静态内部类是不会持有外部类引用的。
修改如下:
public class MainActivity extends AppCompatActivity { private SingleManager manager; //1、使用static创建匿名类的静态实例,不会持有外部类的引用 private static Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); } }; private static MyHandler myHandler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //这里传入当前activity的context,会导致activity没法释放而造成内存泄露 manager = SingleManager.getInstance(this); //延时10分钟发送一个消息 handler.postDelayed(new Runnable() { @Override public void run() { } }, 60 * 10 * 1000); myHandler.postDelayed(new Runnable() { @Override public void run() { } }, 60 * 10 * 1000); finish(); } //2、静态内部类的实例也不会持有外部类的引用 private static class MyHandler extends Handler { @Override public void handleMessage(Message msg) { super.handleMessage(msg); } }}
以上就是我对static关键字的一些总结 (^__^)
- 关键字static的作用
- 关键字static的作用
- static关键字的作用
- static关键字的作用
- static关键字的作用
- Static关键字的作用
- 关键字static的作用
- 关键字static的作用
- static关键字的作用
- static关键字的作用
- static关键字的作用
- 关键字static的作用
- static关键字的作用
- static关键字的作用
- static关键字的作用
- static关键字的作用
- static关键字的作用
- 关键字static的作用
- 6月15日,每日20行。
- JDBC中Statement、PreparedStatement和CallableStatement的使用
- 移动支付的思考
- caffe中tools的万能使用
- jquery各种选择器和函数
- static关键字的作用
- 原生JS实现鼠标悬停图片显示文字效果
- 4.格式
- 拦截器与过滤器
- spring-http-Hessian-rpc示范
- 微信小程序制作心得和体会
- java-Collections
- Java工程师成神之路
- tensorflow的安装