何时应该用静态方法、静态域?

静态域:

class Employee
{
    private int id;
    private static int nextId = 1;
}

如果将域设置为static,那么,每个类中只有一个这样的域。一个类可以有无数个实例,但是只有一个静态域。

每个对象却都有自己的一份拷贝。

这有个简单的应用:

public void setId()
{
    id = nextId;
    nextId++;
}

那么,每实例化一个对象,并且每个对象都调用一次setId()方法,则每个对象的id会递增。

Employee类:

package static_key_word;

public class Employee {
	private int id;
	private static int nextId = 1;
	
	public Employee(){
	}
	
	public void setId(){
		id = nextId;
		nextId++;
	}
	public void print(){
		System.out.println(this.toString());;
		System.out.println("After: id = " + id);
		System.out.println("After: nextId = " + nextId);
		System.out.println();
	}
	
}
Test测试类:

package static_key_word;

public class Test {
	public static void main(String[] args) {
		System.out.println(">>>>>>>>>>>>>>>>e1:");
		Employee e1 = new Employee();
		e1.setId();
		e1.print();
		System.out.println(">>>>>>>>>>>>>>>>e2:");
		Employee e2 = new Employee();
		e2.setId();
		e2.print();
	}
}

输出:

>>>>>>>>>>>>>>>>e1:
After: id = 1
After: nextId = 2

>>>>>>>>>>>>>>>>e2:
static_key_word.Employee@2dbe1f3e
After: id = 2
After: nextId = 3

这里需要注意的是:静态域nextId,即使没有雇员对象,该静态域也是存在的,它属于类。而不是属于任何独立的对象。


静态方法:

静态方法是一种不能向对象实施操作的方法。因为静态方法不能操作对象,所以不能在静态方法中访问实例域,但是静态方法可以访问自身类中的静态域。

下面两种情况下可以使用静态方法:

1. 一个方法不需要访问对象状态

2. 一个方法只需要访问类的静态域


最近Android,遇到一个问题。


原先的代码是这样的:

public class CustomTitleBar{

	private static Activity mActivity;
	private static Button mBtnBack;
	private static Button mBtnSetting;

	/**
	 * @param activity 
	 * @param title 标题名称
	 */
	public static void getTitleBar(Activity activity, String title) {
		mActivity = activity;
		mActivity.requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
		mActivity.setContentView(R.layout.custom_title);
		mActivity.getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
				R.layout.custom_title);
		// 标题名称
		TextView textView = (TextView) activity.findViewById(R.id.head_center_text);
		textView.setText(title);
		
	}
	/**
	 * 
	 * @param activity
	 * @param title 标题名称
	 * @param hasBack 是否有返回键(左上角)
	 * @param hasSetting 是否有设置键(右上角)
	 */
	public static void getTitleBarWhole(Activity activity, String title, boolean hasBack , boolean hasSetting) {
		mActivity = activity;
		mActivity.requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
		mActivity.setContentView(R.layout.custom_title);
		mActivity.getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
				R.layout.custom_title);
		// 标题名称
		TextView textView = (TextView) activity.findViewById(R.id.head_center_text);
		textView.setText(title);
		// 按钮初始化
		mBtnBack = (Button) activity.findViewById(R.id.head_left_image);
		mBtnSetting = (Button) activity.findViewById(R.id.head_right_image);
		// 后退键
		if(hasBack){
			mBtnBack.setVisibility(View.VISIBLE);
			mBtnBack.setBackgroundResource(R.drawable.hw_actionbar_back_normal);
			mBtnBack.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					mActivity.finish();
				}
			});
		}
		else{
			mBtnBack.setVisibility(View.GONE);
		}
		// 设置键
		if(hasSetting){
			mBtnSetting.setVisibility(View.VISIBLE);
			mBtnSetting.setBackgroundResource(R.drawable.btn_setting_normal);
		}
		else{
			mBtnSetting.setVisibility(View.GONE);
		}
	}
	
}

这样,我在每个Activity的OnCreate方法里直接

CustomTitleBar.getTitleBarWhole(this, getResources().getString(R.string.whiteList), true, false);
是不是很方便呢?直接调用静态方法。

但是,出现了如下问题。

我有3个界面,A -> B -> C
A:主界面


B:内存加速


C:正在运行的程序


但是,当我从C界面按返回键退回B界面后,继续按左上角的返回键没有反应。

其实原因很简单,因为我在B、C界面的onCreate方法中都调用了自定义的TitleBar,那么由于静态域mActivity每个类只有一个,在C中该域内容就把B中设置的给覆盖了。

而在C界面按返回键退回去的时候,B界面Activity的生命周期并非从onCreate重新开始执行,onPause -> onResume,并没有执行onCreate,所以就是按了返回键,执行的

mActivity.finish()也是C界面的finish(),所以没有响应。


这么分析来看,该公共类的域和方法并非适合于用static来修饰,所以我们将之改成:

public class CustomTitleBar{

	private Activity mActivity;
	private Button mBtnBack;
	private Button mBtnSetting;

	/**
	 * @param activity 
	 * @param title 标题名称
	 */
	public void getTitleBar(Activity activity, String title) {
		mActivity = activity;
		mActivity.requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
		mActivity.setContentView(R.layout.custom_title);
		mActivity.getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
				R.layout.custom_title);
		// 标题名称
		TextView textView = (TextView) activity.findViewById(R.id.head_center_text);
		textView.setText(title);
		
	}
	/**
	 * 
	 * @param activity
	 * @param title 标题名称
	 * @param hasBack 是否有返回键(左上角)
	 * @param hasSetting 是否有设置键(右上角)
	 */
	public void getTitleBarWhole(Activity activity, String title, boolean hasBack , boolean hasSetting) {
		mActivity = activity;
		mActivity.requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
		mActivity.setContentView(R.layout.custom_title);
		mActivity.getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
				R.layout.custom_title);
		// 标题名称
		TextView textView = (TextView) activity.findViewById(R.id.head_center_text);
		textView.setText(title);
		// 按钮初始化
		mBtnBack = (Button) activity.findViewById(R.id.head_left_image);
		mBtnSetting = (Button) activity.findViewById(R.id.head_right_image);
		// 后退键
		if(hasBack){
			mBtnBack.setVisibility(View.VISIBLE);
			mBtnBack.setBackgroundResource(R.drawable.hw_actionbar_back_normal);
			mBtnBack.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					mActivity.finish();
				}
			});
		}
		else{
			mBtnBack.setVisibility(View.GONE);
		}
		// 设置键
		if(hasSetting){
			mBtnSetting.setVisibility(View.VISIBLE);
			mBtnSetting.setBackgroundResource(R.drawable.btn_setting_normal);
		}
		else{
			mBtnSetting.setVisibility(View.GONE);
		}
	}
	
}
当然,在每个Activity的onCreate函数中:

new CustomTitleBar().getTitleBarWhole(this, getResources().getString(R.string.whiteList), true, false);

这样程序就正常了。


谢谢。本次分享到此结束,很多知识是参考《Java 核心技术》这本书,这是本好书。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值