Java笔记

一、 定义类与类之间的交互关系
1、 泛化(Generalization)可以简单理解为继承关系。具体到 Java 代码就是下面这样。


public class A { ... }
public class B extends A { ... }

2、实现(Realization)一般是指接口和实现类之间的关系
public interface A {…}
public class B implements A { … }

3、聚合(Aggregation)是一种包含关系,A 类对象包含 B 类对象,B 类对象的生命周期可以不依赖 A 类对象的生命周期,也就是说可以单独销毁 A 类对象而不影响 B 对象,比如课程与学生之间的关系。具体到 Java 代码就是下面这样:

public class A {
  private B b;
  public A(B b) {
    this.b = b;
  }
}

4、组合(Composition)也是一种包含关系。A 类对象包含 B 类对象,B 类对象的生命周期跟依赖 A 类对象的生命周期,B 类对象不可单独存在,比如鸟与翅膀之间的关系。具体到 Java 代码就是下面这样:

public class A { 
	private B b; 
	public A() { 
		this.b = new B();
	}
}

6、设计思想
1.单一职责原则
适用对象:模块,类,接口
侧重点:高内聚,低耦合
思考角度:自身

2.接口隔离原则
适用对象:接口,函数
侧重点:低耦合
思考角度:调用者

3.基于接口而非实现编程
适用对象:接口,抽象类
侧重点:低耦合
思考角度:调用者

4.迪米特法则
适用对象:模块,类
侧重点:低耦合
思考角度:类关系

依赖反转原则
高层模块不要依赖低层模块。高层模块和低层模块应该通过抽象来互相依赖。除此之外,抽象不要依赖具体实现细节,具体实现细节依赖抽象。

控制反转
“控制”指的是对程序执行流程的控制,而“反转”指的是在没有使用框架之前,程序员自己控制整个程序的执行。在使用框架之后,整个程序的执行流程通过框架来控制。流程的控制权从程序员“反转”给了框架。

Java 中比较出名的单元测试框架有 Junit、TestNG、Spring Test

关于命名:
1、作用域小的变量(比如临时变量),可以适当地选择短一些的命名方式
2、函数包含 3、4 个参数的时候还是能接受的,大于等于 5 个的时候,参数有点过多了

代码检测工具:checkstyle,findbugs, pmd, jacaco, sonar

异常处理
1、 直接吞掉。具体的代码示例如下所示:

public void func1() throws Exception1 {
  // ...
}

public void func2() {
  //...
  try {
    func1();
  } catch(Exception1 e) {
    log.warn("...", e); //吐掉:try-catch打印日志
  }
  //...
}

2、原封不动地 re-throw。具体的代码示例如下所示:

public void func1() throws Exception1 {
  // ...
}
public void func2() throws Exception1 {//原封不动的re-throw Exception1
  //...
  func1();
  //...
}

3、包装成新的异常 re-throw。具体的代码示例如下所示:

public void func1() throws Exception1 {
  // ...
}
public void func2() throws Exception2 {
  //...
  try {
    func1();
  } catch(Exception1 e) {
   throw new Exception2("...", e); // wrap成新的Exception2然后re-throw
  }
  //...
}

总之,是否往上继续抛出,要看上层代码是否关心这个异常。关心就将它抛出,否则就直接吞掉。是否需要包装成新的异常抛出,看上层代码是否能理解这个异常、是否业务相关。如果能理解、业务相关就可以直接抛出,否则就封装成新的异常抛出。

经验:
入参和中间不可靠变量的异常校验都放在public方法,所有私有方法都以契约的方式不再做参数校验。也就是说 public方法干 1.参数校验 2. 系统一级流程编排 3.统一异常处理 这三件事。
可以不在 private 函数中做 NULL 值或空字符串的判断
如果函数是 public 的,无法掌控会被谁调用以及如何调用,需要校验。

建造者模式(build模式)
一、 使用场景:
1)类的构造函数必填属性很多,通过set设置,没有办法校验必填属性
2)如果类的属性之间有一定的依赖关系,构造函数配合set方式,无法进行依赖关系和约束条件校验
3)需要创建不可变对象,不能暴露set方法。
(前提是需要传递很多的属性,如果属性很少,可以不需要建造者模式)
二、实现方式:
把构造函数定义为private,定义public static class Builder 内部类,通过Builder 类的set方法设置属性,调用build方法创建对象。

三、和工厂模式的区别:
1)工厂模式:创建不同的同一类型对象(集成同一个父类或是接口的一组子类),由给定的参数来创建哪种类型的对象;
2)建造者模式:创建一种类型的复杂对象,通过很多可设置参数,“定制化”的创建对象

原型模式
原型模式有两种实现方法,深拷贝和浅拷贝。浅拷贝只会复制对象中基本数据类型数据和引用对象的内存地址,不会递归地复制引用对象,以及引用对象的引用对象……而深拷贝得到的是一份完完全全独立的对象。所以,深拷贝比起浅拷贝来说,更加耗时,更加耗内存空间。
深拷贝:
在这里插入图片描述

三、泛型
泛型:
1、extends

T extends Number
在这里extends后的BoundingType可以是类,也可以是接口,意思是说,T是在BoundingType基础上创建的,具有BoundingType的功能。
目测是JAVA的开发人员不想再引入一个关键字,所以用已有的extends来代替而已。

重点: 如果你想从一个数据类型里获取数据,使用 ? extends 通配符(能取不能存)

2、?通配符

无边界通配符? 只能用于填充泛型变量T,表示通配任何类型 只是填充方式的一种!!! Box<?> box= new Box(); 但是不能声明 ? x (不行) box=new Box<?> (不行)

3、super

重点: 如果你想把对象写入一个数据结构里,使用 ? super 通配符(能存不能取)

如果你既想存,又想取,那就别用通配符

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值