java菜鸟的优化代码之路
HryReal
while(!dead) { study(); }
展开
-
Effective Java之考虑用序列化代理代理序列化实例(七十八)
我们知道,实现了序列化的类。在反序列化时,实例的创建是由readObject方法来完成的。由于这是一个不同于构造函数的创建类实例的通道,因此在构造函数中的状态约束条件在readObjetc中也得一条不落下的实现。这很让人头大。 而且readObject的出现,让伪字节流攻击和内部域的盗用攻击成为可能。伪字节流攻击就是伪造一个字节流,通过readObject读取,内部域的盗用攻击是指用一个原创 2018-01-09 09:01:30 · 450 阅读 · 0 评论 -
Effective Java之基本类型优于装箱类型(四十九)
基本类型和装箱类型的区别: 1.基本类型只有值,而装箱类型是引用,有值和地址。 2.基本类型默认值不同,见下面程序。 3.基本类型比装箱类型更节省时间和空间。public class test { private static Integer i; private static Character c; private static Float f;原创 2018-01-08 07:22:54 · 304 阅读 · 0 评论 -
Effective Java之通过接口引用对象(五十二)
List list= new ArrayList Map map = new HashMap 这样使用接口而不是类作为参数的类型为什么一般都使用 List list = new ArrayList() ,而不用 ArrayList alist = new ArrayList()呢? 问题就在于List有多个实现类,如 LinkedList或者Vector等等,现在你用的是ArrayL原创 2018-01-08 07:19:11 · 381 阅读 · 0 评论 -
Effective Java之for-each循环优先于for循环(四十六)
for循环的缺点: 对于for循环遍历,我们很容易出现这样的一些低级错误:对于数组for(int i = 0 ; i >100 ; i++)for(int i = 100 ; i >=0 ; i++)我们有时候会写出像这样一时短路写出来的代码~原因很简单,i出现了三次,每个i我们都要小心! 但是for-each循环就不同了,全程都没有出现 i 好吧,何来错误?对于集合原创 2018-01-07 19:57:54 · 240 阅读 · 0 评论 -
Effective Java之将局部变量的作用域最小化(四十五)
这条规则应该是我们平常容易遵守的规则。我们很少会把所有的局部变量在程序的开始就声明出来,大部分人还是习惯在第一次使用它的地方声明。原因很简单,写起来容易,别人读起来也好读。对于平时写代码写的多的人来说,对于局部变量的初始化应该是司空见惯了,可以发现几乎每个局部变量的声明都包含一个初始化表达式,除非try-catch语句块。在这里,书中特意强调了循环的例子:for循环优于while循原创 2018-01-07 19:19:39 · 244 阅读 · 0 评论 -
Effective Java之返回零长度的数组或者集合,而不是null(四十三)
我们经常可以看到这样的代码:private final List cheesesInStock = ...;/** * @return an array containing all of the cheeses in the shop, * or null if no cheese are available for purchase. */ public Cheese[] ge原创 2018-01-07 16:37:33 · 377 阅读 · 0 评论 -
Effective Java之慎用可变参数(四十二)
Java 1.5增加可变参数方法,可变参数方法接受0个或者多个指定类型的参数。 可变参数的机制是通过先创建一个数组,数组的大小为在调用位置所传递的参数数量,然后将参数值传到数组中,最后将数组传递给方法static int sum(int... args) { int sum=0; for(int arg : args) sum += arg; retu原创 2018-01-07 16:08:04 · 520 阅读 · 0 评论 -
Effective Java之慎用重载(四十一)
在Java虚拟机的分派中,我们知道:重载容易产生的问题:重载是根据参数的静态类型选择执行方法,而方法重写是根据参数的动态类型选择执行方法。 例如People p = new Man();那么People是静态类型,Man是动态类型。 覆盖机制很容易让期望落空。因为如果不知道重载是根据参数的静态类型选择执行方法,那么覆盖就不能执行期待执行的方法。因此,应该避免胡乱使用重载机制。慎重使原创 2018-01-07 15:26:19 · 189 阅读 · 0 评论 -
Effective Java之必要时进行保护性拷贝(三十九)
我们来看一个不可变对象的攻守问题:public class Period{ private final Date startTime; private finale Date endTime; public Period(Date startTime , Date endTime)原创 2018-01-07 14:56:38 · 645 阅读 · 0 评论 -
Effective Java之检查参数的有效性(三十八)
检查参数的有效性实际上是满足了这一条普遍原则:应该在发生错误之后尽快检测出错误。例子: 有个数据库查询的例子,传入一个id,查出一个Student对象,然而返回null,如果没有及时检查这个实例是否为空, 那么在后面使用这个实例时会报错 空指针异常,这时要想找到这个实例究竟在什么时候,什么地方变成空的就会难度加大,因为从赋值到使用这段时间,这个实例可能会发生变化。需要注意的地方:原创 2018-01-07 13:37:53 · 323 阅读 · 0 评论 -
Effective Java之坚持使用Overide注解(三十六)
@Override 注解: 表示被注解的方法声明覆盖了超类型中的一个声明 1.我们应该在想要覆盖超类声明的每个方法声明中使用 Override 注解 ; 如果使用了Override注解的方法是重载而不是覆盖,会编译错误。 2.现在的 IDE 都提供了代码检验功能 . 当一个方法没有使用 Override 注解却覆盖了超类方法时 , IDE 就会产生警告 。防止无意的覆盖。这条的内容十分原创 2018-01-07 11:49:31 · 415 阅读 · 0 评论 -
Effective Java之当心字符串连接的性能(五十一)
字符串连接问题: 在jdk1.7之后,字符串连接问题的得到了优化,比如: String s = “a”+“b”+“c”; 会优化为String s = “abc” 但是,值得注意的是,如果是通过循环拼接字符串的话,会产生很多的String对象。这时候,我们一般会选择StringBuffer或者StringBuilder,我们需要了解他们两者的区别:HashTable是线程安全的,很原创 2018-01-08 07:24:01 · 229 阅读 · 0 评论 -
Effective Java之接口优先于反射机制(五十三)
核心反射机制java.lang.reflect提供了“通过程序来访问关于已装载的类的信息”的能力,给定一个Class实例,可以获得Constructor、Method、Field实例,这些对象提供“通过程序来访问类的成员名称、域类型、方法签名等信息”的能力。反射机制允许一个类使用另一个类,即使当前者被编译的时候后者还根本不存在,存在的代价:1.失去编译时类型检查的好处,包括异常检查。2原创 2018-01-08 07:25:21 · 309 阅读 · 0 评论 -
Effective Java之谨慎地使用本地方法(五十四)
本地方法,是指本地程序设计语言(c,或者c++)来编写的特殊方法. 本地方法在本地语言中可移植性任意的计算任务,并且返回到java程序语言.为什么说谨慎使用本地方法?1.如果调用了一个本地方法,那么要在主机上配置好运行这个本地方法的环境。2.如果出现的bug,那么是本地方法出现问题,那么将无法调试3.想利用本地方法来提高性能做法不提倡,原因是JVM也一直在进步,在变快。使用本地原创 2018-01-08 07:27:06 · 411 阅读 · 0 评论 -
Effective Java之对于实例控制,枚举类型优于readResolve(七十七)
Object readResolve()这个方法会紧挨着readObject()之后被调用,该方法的返回值将会代替原来反序列化的对象,而原来readObject()反序列化的对象将会立即丢弃。readObject()方法在序列化单例类时尤其有用。当然,如果使用java5提供的enum来定义枚举类,则完全不用担心,程序没有任何问题。我们从一个单例模式开始: public原创 2018-01-09 09:00:43 · 777 阅读 · 0 评论 -
Effective Java之保护性编写readObject方法(七十六)
readObject方法实际上相当于另一个公有的构造器,与其他构造器一样,它也需要进行参数的有效性检查与保护性拷贝。参考:Effective Java之必要时进行保护性拷贝(三十九)原因很简单,为了避免客户端修改可变对象,服务器把可变对象的引用指向了客户端找不到的地方,但是默认反序列化的过程把客户端找不到的地方给了客户端,给了客户端修改的机会,导致了错误,readObject也应该完成构造器做原创 2018-01-09 08:59:30 · 409 阅读 · 0 评论 -
Effective Java之考虑自定义的序列化模式(七十五)
为什么自定义序列化?这里直接举一个书上的例子public final class StringList implements Serializable { private int size = 0; private Entry head = null; private static class Entry implements Serializable {原创 2018-01-09 08:58:04 · 434 阅读 · 0 评论 -
Effective Java之谨慎地实现Serializable(七十四)
1.序列化的含义和作用序列化用来将对象编码成字节流,反序列化就使将字节流编码重新构建对象。 序列化实现了对象传输和对象持久化,所以它能够为远程通信提供对象表示法,为JavaBean组件提供持久化数据。2.序列化的危害1.降低灵活性:为实现Serializable而付出的最大代价是,一旦一个类被发布,就大大降低了”改变这个类的实现”的灵活性。如果一个类实现了Serializable,它原创 2018-01-09 08:57:08 · 855 阅读 · 0 评论 -
Effective Java之不要忽略异常(六十五)
任何一个被抛出的异常都是API设计者有意为之的,其中蕴含了特定的含义,所以千万不能忽略它们! try{ ...... }catch (Exception e){ } 这样的代码并不十分罕见,这有可能是在代码堆砌阶段的“简单写法”,也可能是程序员“偷懒”的写法,当然也有可能是连“何为Exception”都不得而知的“高人”的作品。这里犯了两个错误。 首先原创 2018-01-09 08:55:36 · 334 阅读 · 0 评论 -
Effective Java之努力使失败保持原子性(六十四)
这是我们需要遵守的规则:1.失败的方法调用应该使对象保持在被调用之前的状态。 2.错误通常是不可恢复的,当方法抛出错误时,不需要保持原子性。 3.作为方法规范的一部分,方法产生的任何异常都应该让对象保持在该方法调用之前的状态。如果违反这条规则,API文档就应该清楚地指明对象将会处于什么样的状态。失败原子性实现方法1.对象为不可变对象,那么对象创建出来就不能被修改了,也不需要维护。原创 2018-01-09 08:54:51 · 459 阅读 · 0 评论 -
Effective Java之在细节消息中包含能捕获失败的消息(六十三)
程序为捕获的异常而失败,系统会自动打印该异常的堆栈轨迹,在堆栈中包含该异常的字符串表示法(它的toString方法结果,包含类名,消息细节), 在这种情况下,我们有时看到一长串类名和自动生成的错误消息无从下手,究竟错误出现在了哪里?这种情况的发生其实和Object的toString方法类似,我输出一个对象,调用你的toString方法显示出来的东西没有价值,要你何用?我程序出现异常,返回的信息原创 2018-01-09 08:54:09 · 184 阅读 · 0 评论 -
Effective Java之抛出与抽象相应的异常(六十一)
1.如何处理异常? 方法B抛出了一个受检的异常 ,那么方法A在内部调用方法B时,面对方法B抛出的受检异常,可以选择继续抛出向上传播这个异常,也可以捕获这个异常进行处理。究竟是向上传播抛出,还是捕获处理呢?2.处理异常方法方法一:抛出与抽象想对应的异常。 例如 如果方法B抛出了NoSuchElementException这个受检异常,然而在方法A中调用方法B时,根据方法A中的逻辑,当遇原创 2018-01-08 09:33:35 · 348 阅读 · 0 评论 -
Effective Java之优先使用标准的异常(六十)
Java平台类库提供了一组基本的未受检的异常,他们满足了绝大部分API的异常抛出异常。为什么优先使用标准异常1.它使你的API可读性更强,因为它与程序员习惯的用法一致。 2.异常类越少,程序在类装载阶段的负担就越少,时间开销也越少。怎么使用标准异常常用的标准异常: IllegalArgumentException 参数不符合条件 IllegalStateExceptio原创 2018-01-08 08:53:42 · 222 阅读 · 0 评论 -
Effective Java之避免使用受检的异常(五十九)
1.如何使用受检的异常?如果一个方法抛出了一个或者多个异常,那么调用该方法的代码就必须在一个或者多个catch块中处理这些异常,或者方法上抛出这些异常,并让他们传播出去,无论是哪种方法,都给程序员带来了负担。2.如何避免使用受检的异常?异常的设计原则是在不正常的的情况下处理,如果可以把不正常的情况改变为正常思路下的部分,那么可以减少异常处理.不正常是特例,正常才是主流。把”受检异常原创 2018-01-08 08:35:44 · 206 阅读 · 0 评论 -
Effective Java之对可恢复的情况使用受检异常,对编程错误使用运行时异常(五十八)
java将所有的错误封装为一个对象,其根本父类为Throwable, Throwable有两个子类:Error和Exception。 异常分成三种结构1.错误:Error是Throwable 的子类,用于指示合理的应用程序不应该试图捕获的严重问题。 在执行该方法期间,无需在其 throws 子句中声明可能抛出但是未能捕获的 Error的任何子类,因为这些错误可能是再也不会发生的异常条件原创 2018-01-08 08:09:09 · 654 阅读 · 0 评论 -
Effective Java之注解优于命名模式(三十五)
Java 1.5之前,一般使用命名模式表明有些程序元素需要通过某种工具或者框架进行特殊处理。例如,JUnit测试框架原本要求用户一定要用test作为测试方法名称的开头。命名模式的缺点:文字拼写错误导致失败,测试方法没有执行,也没有报错 无法确保它们只用于相应的程序元素上,如希望一个类的所有方法被测试,把类命名为test开头,但JUnit不支持类级的测试,只在test开头的方法中生效原创 2018-01-07 11:14:35 · 426 阅读 · 0 评论 -
Effective Java之用接口模拟可伸缩的枚举(三十四)
在实际工作中,我们常常会遇到这样的情况:如果我在一个枚举类型封装在一个jar库里后,其他开发人员如果对该枚举进行扩展? 毕竟我刚开始定义的枚举并不是会涵盖所有的可能!public enum ModuleType{RESOURCE_MODULE,//......}这样的情况下,由于我们知道enum虽然没写final,但是它是一个真正实现了final的类,所以不支持扩展,那么这种情原创 2018-01-07 09:40:13 · 259 阅读 · 0 评论 -
Effective Java之EnumMap代替序数索引(三十三)
Map的实现类有很多种,EnumMap从名字我们可以看出这个Map是给枚举类用的。它的key为枚举元素,value自定义。在工作中我们也可以用其他的Map来实现我们关于枚举的需求,但是为什么要用这个EnumMap呢? 因为它的性能高!为什么性能高? 因为它的内部是用数组的数据结构来维护的!我们可以看一下它的源码实现:Put方法public V put(K key, V value) {原创 2018-01-06 22:17:35 · 313 阅读 · 0 评论 -
Effective Java之消除过期的引用(六)
容易出现内存泄漏问题的情景:1.自己管理内存的类。书中举出了一个内存泄漏的stack例子class Stack{public Object[] elements;//原文为private,但这里改为public为了测试下面代码public int size=0;public Stack(int initialCapacity){this.elements=new Object[initialCapa原创 2017-12-12 16:47:20 · 470 阅读 · 0 评论 -
Effective Java之避免创建不必要的对象(五)
1.对于不可变类(immutable),他始终可以被重用。如:String类 String s = new String(“string”); 这种方法创建了两个String对象,因为传入String构造器的参数本身就是一个String实例,new再创建一个对象,由s指向它,事实上这样做浪费了两倍内存。 所以应该这样: String s = “string”;又如:Integer类等包装类原创 2017-12-12 16:13:56 · 616 阅读 · 0 评论 -
Effective Java之通过私有构造器强化不可实例化能力(四)
比如很多工具类,成员都是静态的,你写这个类的原因是想拿来直接用,而不需要实例化的但是在缺少显示构造函数的时候,编译器会给你默认生成一个构造函数,这样这个类就有可能实例化企图将类做成抽象类来强制该类不被实例化,这是行不通的(因为子类可以实例化,而且你写这个类不又不是用来继承的)将构造器设置为private来解决问题:public class UtilityClass { // Suppress原创 2017-12-12 15:20:47 · 541 阅读 · 0 评论 -
Effective Java之多个构造参数考虑用构建器(二)
静态工厂方法和构造器都有一个共同的特点–>无法扩展到大量的参数。对于大量的参数类,我们有以下方案: 1.重叠构造器。这个源码中经常可以看到,例如HashMap: public HashMap(int initialCapacity, float loadFactor) { if (initialCapacity < 0) throw new IllegalA原创 2017-12-12 13:56:07 · 454 阅读 · 0 评论 -
Effective Java之静态工厂代替构造器(一)
优势1:它们有名称,所以在多个构造器时,能够根据静态工厂的方法的名称找到哪个构造器。优势2:能够实现单例模式,不必在每次调用重新创建新对象。优势3:当创建参数化参数实例时,使用静态工厂方法更加简单。优势4:它们可以返回原返回类型的任何子对象。 书中提到了展示这个优势的“服务提供者框架”,我们以jdbc为例,来看一下jdbc是如何利用静态工厂的。定义 多个服务提供者实现一个服务,系统为服务提供原创 2017-12-12 12:34:55 · 459 阅读 · 0 评论 -
Effective Java之使可变性最小(十五)
为了使类变成可变类,需要遵循以下原则: 1.不要提供任何修改对象状态的方法。 2.保证类不会被扩展,声明类为final。 3.保证所有的域都是final的。 4.保证所有的域都是私有的。不可变类的优点: 1.不可变类 简单,它在生命周期内只有一种状态。 2.不可变对象线程安全,不要求同步。 3.对于频繁使用的值,可以提供公有的静态final方法,并将其缓存起来,降低内存和垃圾回收成本。原创 2017-12-19 21:36:15 · 169 阅读 · 0 评论 -
JAVA虚拟机运行数据区
1.程序计数器 程序计数器是一段小的内存空间,可以把它看成当成线程所执行的字节码的行号指示器。因此,他是线程私有的,生命周期与线程相同。 如果线程执行的是Java方法,则计数器记录的是正在执行的虚拟机字节码指令的地址;如果是Native方法,则计数器为空。2.JAVA虚拟机栈 虚拟机栈也是线程私有的,它描述的是Java方法执行的内存模型。每个方法对应一个栈帧,存储这个方法的各种原创 2017-10-29 19:47:37 · 245 阅读 · 0 评论 -
Java的io类的使用场景
先附上io图: InputStream类ByteArrayInputStream – 把内存中的一个缓冲区作为 InputStream 使用,CPU从缓存区读取数据比从存储介质的速率快10倍以上。StringBufferInputStream – 把一个 String 对象作为。InputStream。不建议使用,在转换字符的问题上有缺陷。FileInputStream – 把一个文件作为原创 2017-11-12 16:04:41 · 17912 阅读 · 0 评论 -
java数组与C++数组的不同之处
1.声明java数组要不能声明为int a[10]; 否则会在编译时出错Syntax error on token "10", delete this token2.赋值第一种方式int a[]=new int[2];这样直接在堆中创建数组对象赋给引用a; 第二种方式int a[]={2,2,2}数组的长度取决于填的个数。 与c++不同的地方在于,java可以自动对空数组,也就是没有初始化的数原创 2017-05-31 17:17:39 · 1065 阅读 · 0 评论 -
JAVA内存存储数据的位置
有5个地方可以存储数据1.寄存器因为寄存器位于不同于其他存储区的地方—处理器内部,所以这是最快的存储区。正因为它的大小极其有限,所以它会按照需求分配,在程序中,你不能对它进行任何操作,甚至感受不到它的存在。2.堆栈堆栈位于RAM(随机访问存储器)中,通过堆栈指针来处理内存,堆栈指针向下移动,则分配新的内存,如果向上移动,则释放内存,这是一种快速有效的分配存储方式。 JAVA系统必须知道它们的确切生原创 2017-05-31 16:39:43 · 1041 阅读 · 0 评论 -
使类和成员的可访问性最小化
模块之间只能通过api进行通信,也就是通过暴露出来的预先定义好的函数进行通信,一个模块不需要,也不应该知道其他模块的内部工作情况,这个概念叫做信息隐藏,,也叫封装,是软件设计的重要的基本原则之一。之所以重要,是因为它能有效地解除各模块的耦合关系,使得各模块能够进行独立的开发,测试,优化,使用和修改。原创 2016-08-30 17:44:14 · 16322 阅读 · 0 评论 -
Effective Java之用私有构造器或者枚举类型强化Singleton属性(三)
1.饿汉式加载类加载时就创建public class MaYun {private static Mayun instance = new Mayun();private static getInstance() {return instance;}private MaYun() {//MaYun诞生要做的事情}public void splitAlipay() {System.o原创 2017-12-12 14:54:42 · 552 阅读 · 0 评论