创建和销毁对象

第1条:用静态工厂方法代替构造器

优点:

  1. 相较于构造方法,通过静态工厂创建对象能够使得用户对类的使用更加直观(后续开发中进行尝试)
    public static Child newChild(int age, int weight) {
        Child child = new Child();
        child.weight = weight;
        child.age = age;
        return child;
    }
    替代   new Child(int age,int weight) 
  1. 生成单例,避免每次都创建对象,浪费空间(视情况选择)
  2. 可以返回子类型对象,根据自己的需要进行返回 ()
public static Father newChild(int age, int weight) {
        Child child = new Child();
        child.weight = weight;
        child.age = age;
        return child;
    }

4.返回的类可以随着每次调用而动态变化,这取决于静态工厂的方法的参数值。可根据传入不同的参数或者值,来返回不同的类,即简单工厂模式

5.静态工厂返回的类可以不存在

例子:服务提供者框架

//四大组成之一:服务接口
public interface LoginService {//这是一个登录服务
    public void login();
}
//四大组成之二:服务提供者接口
public interface Provider {//登录服务的提供者。通俗点说就是:通过这个newLoginService()可以获得一个服务。
    public LoginService newLoginService();
}
/**
 * 这是一个服务管理器,里面包含了四大组成中的三和四
 * 解释:通过注册将 服务提供者 加入map,然后通过一个静态工厂方法 getService(String name) 返回不同的服务。
 */
public class ServiceManager {
    private static final Map<String, Provider> providers = new HashMap<String, Provider>();//map,保存了注册的服务
    private ServiceManager() {
    }
    //四大组成之三:提供者注册API  (其实很简单,就是注册一下服务提供者)
    public static void registerProvider(String name, Provider provider) {
        providers.put(name, provider);
    }
    //四大组成之四:服务访问API   (客户端只需要传递一个name参数,系统会去匹配服务提供者,然后提供服务)  (静态工厂方法)
    public static LoginService getService(String name) {
        Provider provider = providers.get(name);
        if (provider == null) {
            throw new IllegalArgumentException("No provider registered with name=" + name);
        }
        return provider.newLoginService();
    }
}

想要增加服务时只需要实现服务提供者接口、服务接口,然后约定一个服务名就可以了。

第二条 遇到多个构造器参数时要考虑使用构建器

1.重叠构造器

为各种参数配置多个构造器,缺点:参数过多时,实现繁琐

2.javaBeans

new 一个无参的对象,再通过set进行设置参数,缺点:线程安全无法保证

3.建造者模式(Builder)
  1. 需要一个构造函数用来存放Builder,将Builder的参数存放到对象中

    private Person(Builder builder) {    
    this.name = builder.name;    
    this.homeAddr = builder.homeAddr;    
    this.tel = builder.tel;    
    this.workAddr = builder.workAddr;}
    
  2. 需要一个内部静态类Builder,参数与person相同,并且存在与参与名相同的方法,作用的将值存放到Builder对象中,并返回

public static class Builder {    
private String name;    
private String workAddr;    
private String homeAddr;    
private int tel;    
public Builder() {}
public Builder name(String name) {        
     this.name = name;        
     return this;    
}    
......
  1. 内部静态类Builder中,还需要一个builder方法,将Builder对象传入后,返回对象

    public Person build() {    
        return new Person(this);}
    
  2. 创建对象的方法

    Person person = new Person.Builder.name().builder();
    

第三条 用私有构造器或者枚举类型强化Singleton属性

单例实现的四种方式:

  1. 懒汉式

  2. 饿汉式

  3. DCL

  4. 枚举类型,优点是防止反射,序列化new对象 ,最佳方法

    public enum EnumTest {
        IN;
        private String name;
        private EnumTest(){}
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }
    
    public static void main(String[] args) throws Exception {    
            EnumTest in = EnumTest.IN;    
            in.setName("111");}
    

第四条 通过私有构造器强化不可实例化的能力

private 的构造方法,使得不可被外部实例化 。。。但是能被反射实例化

第五条 优先考虑依赖注入来引用资源

通过传入对象来实现,而不直接指定特定对象。

public class Person {
    Phone phone = IPhone.getInstance();
    public void playGame() {
        phone.playGame();
    }
    public static Person getInstance() {
        return new Person();
    }
}

依赖注入

public class Person {
    Phone phone;
    public void playGame() {
        phone.playGame();
    }
    // 构造方法注入
    private Person(Phone phone) {
        this.phone = phone;
    }
}

第六条 避免创建不必要的对象

1.字符串最好抽成常量,不要出现魔法值

2.不要每次都创建对象,根据情况进行优化,但需要考虑对象的拷贝问题

3.自动装箱,优先使用基本数据类型,而不是装箱类,装箱类是对象,但是在网络请求时,最好使用装箱类,因为装箱类实现了序列化。

第七条 消除过期的对象引用

1.类自己管理内存时,需要警惕内存泄漏问题

2.缓存可以放到WeakHashMap,弱引用,当对象不被引用就被回收

3.监听器和其他回调

第八条 避免使用终结方法和清除方法

第九条 try-with-resources 优先于 try-finally

try-finally 当try阶段和finally阶段都出现异常时,只能显示finally的异常

public class Connection implements AutoCloseable {
    public void sendData() throws Exception {
        throw new IOException("send data");
    }
    @Override
    public void close() throws Exception {
        throw new Exception("close");
    }
}
public static void main(String[] args) throws Exception {
        Connection connection = null;
        try{
            connection = new Connection();
            connection.sendData();
        }finally {
            if(connection!= null){
                connection.close();
            }
        }
    }

异常信息

Exception in thread "main" java.lang.Exception: close
	at com.example.demo.controller.Connection.close(Connection.java:21)
	at com.example.demo.controller.UserController.main(UserController.java:24)

换成 try-with-resource写法 就是将资源生成语句写在try()中

    public static void main(String[] args) {
        try (Connection connection = new Connection()) {
            connection.sendData();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

异常信息 两次异常信息都被打印出来

java.io.IOException: send data
	at com.example.demo.controller.Connection.sendData(Connection.java:16)
	at com.example.demo.controller.UserController.main(UserController.java:18)
	Suppressed: java.lang.Exception: close
		at com.example.demo.controller.Connection.close(Connection.java:20)
		at com.example.demo.controller.UserController.main(UserController.java:19)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值