看看我们的资料:4000G Java架构师资料(需要的话关注留言)
主要内容:21套Java精品高级课架构课包含:java8新特性,P2P金融项目,程序设计,功能设计,数据库设计,架构设计,web安全,高并发,高性能、高可用、高可扩展,分布式,集群,电商,缓存,性能调优,设计模式,项目实战,工作流,程序调优,负载均衡,Solr集群与应用,主从复制,中间件,全文检索,Spring boot,Spring cloud,Dubbo,Elasticsearch,Redis,ActiveMQ,Nginx,Mycat,Spring,MongoDB,ZeroMQ,Git,Nosql,Jvm,Mecached,Netty,Nio,Mina,Nutch,Webservice,Activiti,Shiro,Tomcat,大型分布式电商实战等高端视频课程......,Android、ios、微信小程序移动app应用,以及2017年最火的大数据(hadoop、hbase、hive、spark、storm等),python,人工智能能智能。
获取方式:关注头条号留言即可
接着上期继续看本书高质量编码建议17~22条的阅读笔记
17.要么为继承而设计,并提供文档说明,要么禁止使用继承
不要过度设计。
面向对象编程,从一开始被洗脑难免在上手写代码时都会首先思考有没有公共方法啊,能不能把两个类抽象成一个父类再继承啊等,慎重使用继承,当要使用继承时一定要在文档注释中写明重写这个方法会给其他方法带来什么影响。书中给出建议如果类并不是为了继承而生,那么这个类应该用final修饰禁止子类化。
18.接口优先于抽象类
接口和抽象类的异同这是Java基础中的基础。我们不妨来回顾下接口和抽象类的区别:
接口不能被实例化不能有构造器,抽象类也不能被实例化但可以有构造器;
接口中不能有实现方法(JDK8在接口中可以有实现方法,称“默认方法”),抽象类中可以有实现方法,也可以没有;
接口方法的默认修饰符就是public,不可以用其他修饰符,抽象类可以有public、protected、default。
回到“接口优于抽象类”的问题上来,原因就是Java只支持单继承,但可以实现多个接口。有抽象类的地方基本上都可以看到其中的方法很多是模板方法
19.接口只用于定义类型
这个条目中建议接口不要只用于定义常量使之成为常量接口,如果一个类只有常量应该使用枚举类型或者不可实例化的工具类。JDK中的反例就是java.io.ObjectStreamConstant。
20.类层次优先于标签类
标签类是指在类中定义了一个变量,使用该变量的值来控制该做什么动作。
书中举例:定义一个Figure类,使用Shapre变量,可以传入“长方形”或者“圆形”,根据传入的类型不同调用共同的方法。这个就是一个标签类,如果新增一个“三角形”的话,就得修改这个标签类的代码。
更好的方法就是利用继承,合理利用继承能更好的体现面向对象的多态性。
21.用函数对象表示策略
什么是函数对象?实际上这是在JDK8之前没有Java不支持lamda表达式,方法参数不能传递一个方法只能通过传递对象的方式“曲线救国”,例如Arrays.sort(T[] a, Comparator<? super T> c)方法,第一个参数传递数组,根据传入第二个自定义的比较类中的比较方法进行排序。如果能传入函数指针、lambda表达式等,那就自然不用传递一个类。
从JDK8开始Java已经支持了lambda表达式,不妨简单了解下JDK8的lambda表达式。
广义上来讲JDK8中lambda表达式有两个部分组成:一是lambda表达式本身,二是函数式接口。函数式接口实际上就是指只包含一个抽象方法的接口,比如Runnable接口只包含run抽象方法。而lambda表达式本身实际上则是对抽象方法的实现。
首先lambda表达式的语法格式如下所示:
例如
(n)->Sy(n);
表示打印n。
上面提到lambda是对抽象方法的实现,那么实际上这条lambda表达式对应的就是:
public void demo(String n){
Sy(n);
}
lambda表达式不过是一个匿名方法实现而已,接下来我们看看到底是如何使用lambda表达式。
/**
* 函数式接口,只包含一个抽象方法
*/
public interface LambdaDemo {
void demo(String n);
}
/**
* lambda例子
*/
public class App {
public static void main( String[] args ) {
LambdaDemo lambdaDemo = (n) -> Sy(n); //实例化LambdaDemo类,同时也lambda表达式实现了demo方法
lambdaDemo.demo("hello lambda");
}
}
22.优先使用静态成员类
一般情况下我们可能提到最多的是“内部类”这个名词,实际上在类“内部”的类叫做“嵌套类”。嵌套类分为四种:静态成员类、非静态成员类、匿名类和局部类。除了静态成员类,其余三种才被称之为内部类。
匿名类提及的比较多:
public class App {
public static void main( String[] args ) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
Sy("这是一个内部类");
}
}); //回顾一下lambda表达式,可表示为Thread thread = new Thread(() -> Sy("这是一个内部类"));
();
}
}
静态成员类相比较于非静态成员类就是多了一个static关键字修饰类,另外一个更重要的区别在于非静态成员类的每个实例都包含一个额外的指向外围对象的引用,保存这份引用要耗费时间和空间。
举个例子,在JDK7中,HashMap内部使用Entry类表示每个键-值对,这个类是static静态的,如果将static去掉仍然可以工作,但每个entry中将会包含一个指向该Map的引用,这样就浪费了空间和时间。
那么什么时候使用静态什么时候使用非静态呢?
书中给出了比较明确的原则:如果声明成员类不要求访问外围实例,就要始终把static修饰符放在它的声明中。也就是说如果成员类和外围实例类有交互,那这个类就应该是非静态的,如果没有交互而是作为外围类的一个组件存在在应使用静态的。
最后一个是局部类,只要是在任何“可以声明局部变量的地方”,都可以声明局部类,用得最少,如果要使用那也必须非常简短。
今天就这么多了,明天持续更新,下期内容:
23.请不要在新代码中使用原生态类型
24.消除非受检警告
25.列表优先于数组
获取方式:关注头条号留言即可