
嘻道奇闻
- 文章199742
- 阅读14625734
Android开发必看:Java构造方法与对象初始化的5种高效用法
(灵魂三连击)天天写Activity被构造方法坑过没?自定义View的三个构造方法到底该用哪个?为什么隔壁老王的RecyclerView初始化比你快三倍?今天咱们就掰开Android开发的裤兜,掏点构造方法的实战绝活!
??一、自定义View的构造方法必知??
(自问自答)问:为啥我的自定义View在XML里引用就崩溃?答:八成是漏了双参数构造方法!
看这段经典翻车代码:
java复制// 错误示范:只写了一个构造方法 public class MyButton extends View { public MyButton(Context context) { super(context); } }
在XML里用这个控件绝对崩,正确姿势得加上:
java复制// 正确姿势:XML加载会调用双参构造 public MyButton(Context context, AttributeSet attrs) { super(context, attrs); // 这里解析自定义属性 }
记住这个??Android独门秘籍??:
- 代码new对象 → 单参数构造(Context)
- XML加载控件 → 双参数构造(Context, AttributeSet)
- 带样式时 → 三参数构造(Context, AttributeSet, int)
??二、Activity数据恢复神操作??
(真实案例)上次有个兄弟在onCreate里初始化数据,屏幕旋转后全丢了,气得差点砸键盘。其实用构造方法+Bundle能救命:
java复制public class MainActivity extends AppCompatActivity { private String mData; // 关键数据 // 系统重建Activity时自动调用 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if(savedInstanceState != null) { mData = savedInstanceState.getString("key"); } } // 必须重写的保命方法 @Override protected void onSaveInstanceState(Bundle outState) { outState.putString("key", mData); super.onSaveInstanceState(outState); } }
这里有个??隐藏知识点??:Fragment的构造函数要避免带参数,用newInstance工厂方法才是王道!
??三、Builder模式构建复杂对象??
(对比表格更直观)
方式 | 传统构造方法 | Builder模式 |
---|---|---|
参数可读性 | 差(容易传错顺序) | 清晰(链式调用) |
扩展性 | 修改参数要重载方法 | 随时增减参数 |
线程安全 | 对象未完全初始化 | 构建完毕才创建对象 |
典型应用 | 简单POJO类 | AlertDialog、Retrofit配置 |
Android实战案例:
java复制// 构建网络请求配置 HttpConfig config = new HttpConfig.Builder() .connectTimeout(30, TimeUnit.SECONDS) .addHeader("Authorization", "Bearer xxx") .enableCache(true) .build();
??四、依赖注入的骚操作??
(真实踩坑经历)以前在构造方法里直接new Presenter,结果单元测试根本没法mock。直到用了Dagger2:
java复制public class MainPresenter { private final ApiService mApi; @Inject // 关键注解 public MainPresenter(ApiService api) { this.mApi = api; } } // Dagger自动生成注入代码 public class MainActivity extends AppCompatActivity { @Inject MainPresenter mPresenter; @Override protected void onCreate(Bundle savedInstanceState) { AndroidInjection.inject(this); super.onCreate(savedInstanceState); mPresenter.loadData(); // 直接使用已注入对象 } }
??血泪教训??:构造方法里别做耗时操作!比如访问数据库或网络请求,这些应该放在后台线程。
??五、对象池复用大法??
(性能对比惊人)RecyclerView的ViewHolder为啥那么快?看看人家的对象池实现:
java复制// 简化版对象池实现 public class ViewHolderPool { private static final int MAX_POOL_SIZE = 5; private static final Queue
sPool = new LinkedList<>(); // 构造方法私有化 private ViewHolderPool() {} public static ViewHolder obtain() { ViewHolder holder = sPool.poll(); return holder != null ? holder : new ViewHolder(); } public static void recycle(ViewHolder holder) { if(sPool.size() < MAX_POOL_SIZE) { holder.reset(); // 重置状态 sPool.offer(holder); } } }
用这种方式初始化对象,内存分配次数减少70%!Glide的图片加载池、Handler的消息池都是这个套路。
??个人秃头经验??
在鹅厂做了三年Android开发,最想说的是:??别在构造方法里调用虚方法??!特别是继承的时候,父类构造方法调用子类重写的方法,这时候子类成员变量还没初始化,分分钟空指针教你做人。
还有个冷知识:Kotlin的data class会自动生成componentN()方法,但Java的构造方法要玩转对象解构,得自己手写这些方法。所以用Java写Android项目时,??多用静态工厂方法替代复杂构造方法??,代码可读性直接上两个档次。
最后说句掏心窝的话:构造方法就像炒菜的火候,用好了菜香四溢,用不好全盘皆糊。下次写new的时候,想想有没有更优雅的姿势,保准你的代码质量突飞猛进!