详细描述Java高级优化技术及里氏置换原则(Liskov Substitution Principle)

Ⅰ、Java高级优化技术常用如下几点:

1.优化循环。通过重新组织重复的子表达式来提高循环体的运行性能。

2减少使用对象的数量来提高运行性能。

3.缩减网络传输数据来缩短等待时间。

其他:

1.采用对象池技术,提高对象的利用效率。

性能的损耗主要源于创建和释放对象,因此要避免对象的创建和释放。采用对象池技术,预先定义一个对象池,预先创建一组待使用的对象:

Enemy[5] enemy=new Enemy[5];

for(int i=0;i<5;i++){

enemy[i]=new Enemy();

}

增加标志如used和reset标识Enemy的状态。需要创建对象时从对象池中获取 一个未被使用的对象并用reset方法初始化;需要释放时只需修改标志位以供下次使用即可。
2.尽可能使用基本数据类型代替对象

例如用二维数组代替一个写简单的对象。

3.优化算法

比如对于默写不要求很精细的场景和算法,用简单的算法模拟。

4.其他优化

a.如提取字符串时,试着返回子串而不是创建一个副本。

b.尽量的少创建短期的临时对象。

c.能用库函数的就不要自己创建(库函数是优化好的)

d.Map map=new HashMap();

HashMap map=new HashMap();  //这个性能更高,重构代码

e.增强型for循环和Iterable使用时,多了一个对象的创建,慎用。

f.避免enum类型。

g.嵌入式开发时注意浮点的运用,尽量不用。(处理器是否支持浮点)

h.图片资源压缩、多张图片集中到一张图片上(比单独的和小很多,省去了每张的头文件、结束文件等数据块,合并了调色板)

Ⅱ、里氏置换原则(Liskov Substitution Principle),简称LSP

定义:

Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.

所有引用基类的地方必须能够透明的使用其子类对象。

也就是说,只要父类出现的地方子类就能够出现,而且替换为子类不会产生任何错误或异常。但是反过来,子类出现的地方,替换为父类就可能出现问题了。

这个原则是为良好的继承定义一个规范,简单的讲,有4层含义:

  一、子类必须完全实现父类的方法

定义一个抽象类

public abstract class ViewPoint { //去丽江旅游public abstract void where();}下面两个类是实现这个抽象类

public class Lijiang extends ViewPoint {

@Override public void where() { System.out.println(”欢迎来到丽江……”);}

} public class Zhangjiajie extends ViewPoint {

@Override public void where() { System.out.println(”欢迎来到张家界……”);}

}人物是涂涂,在里面设置类类型来传递参数。此时涂涂要去的旅游景点还是抽象的

public class Tutu { //定义要旅游的景点private ViewPoint viewpoint;//涂涂要去的景点public void setViewPoint(ViewPoint viewpoint)

{ this.viewpoint = viewpoint;}

public void travelTo()

{ System.out.println(”涂涂要去旅游了”);viewpoint.where();}场景类。设置具体要去的景点

public class Sence { public static void main(String args[])

{ Tutu tutu = new Tutu();//设置要去的旅游景点tutu.setViewPoint(new Lijiang());tutu.travelTo();}运行结果:

涂涂要去旅游了

欢迎来到丽江……

  二、子类可以有自己的特性

也就是说在类的子类上,可以定义其他的方法或属性

  三、覆盖或者实现父类的方法时输入参数可以被放大

父类能够存在的地方,子类就能存在,并且不会对运行结果有变动。反之则不行。

父类,say()里面的参数是HashMap类型,是Map类型的子类型。(因为子类的范围应该比父类大)

import java.util.Collection;import java.util.HashMap;

public class Father { public Collection say(HashMap map)

{ System.out.println(”父类被执行……”);return map.values();}子类,say()里面的参数变成了Map类型,Map范围比HashMap类型大,符合LSP原则。注意这里的say不是覆写父类的say,因为参数类型不同。而是重载。

import java.util.Collection;import java.util.Map;

/* * 子类继承了父类的所有属性*/ public class Son extends Father { //方法输入参数类型public Collection say(Map map)

{ System.out.println(”子类被执行……”);return map.values();}场景类

import java.util.HashMap;

public class Home { public static void main(String args[])

{ invoke();}

public static void invoke()

{ //父类存在的地方,子类就应该能够存在//Father f = new Father();Son s = new Son();HashMap map = new HashMap();//f.say(map);s.say(map);}无论是用父类还是子类调用say方法,得到的结果都是

父类被执行……

但是,如果将上面Father里的say参数改为Map,子类Son里的say参数改为HashMap,得到的结果就变成了

f.say(map)结果:父类被执行……

s.say(map)结果: 子类被执行……

这样会造成逻辑混乱。所以子类中方法的前置条件必须与父类中被覆写的前置条件相同或者更宽。

  四、覆写或者实现父类的方法时输出结果可以被缩小

其实与上面的类似,也就是父类能出现的地方子类就可以出现,而且替换为子类不会产生任何错误或者异常,使用者也无需知道是父类还是子类。但是反过来就不行了,有子类出现的地方,父类未必就适应。(毕竟子类的范围要>=父类的范围)