首页 > 奇闻 > 正文内容

Android开发必看:Java构造方法与对象初始化的5种高效用法

奇闻2025-05-27 11:44:51

(灵魂三连击)天天写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的时候,想想有没有更优雅的姿势,保准你的代码质量突飞猛进!

搜索