《Java程序员上班那点事儿》自我小结2

文接上一篇,继续整理。

13、异常处理对程序品质的影响

(1)没有对捕获后的异常做任何处理。

     例:catch(Exception eii){

             Eii.printStackTrace();

             }

PrintStackTrace()不代表对异常做了处理,他只是将异常打印出来,让调试人员可以看到这个错误的细节。然而如果程序已交付给用户,则该语句没有任何意义。

(2)不管什么异常都用Exception来捕获。

     用Exception捕获所有异常是一种“理想”想法,但实际情况很不可取。不管出现什么异常都用一种异常类型进行捕获,根本无法做出相应异常的特殊处理。Catch语句应该尽量指定具体的异常类型,而不应该指定涵盖范围太广的Exception类。

(3)资源占用没有释放。

     如果程序用到了IO、Socket、JDBC等类,即使遇到异常,跳出{}的话,也应该释放所占用的系统资源。Java提供了一个简化的完成这种操作的方法,这个方法就是finally。Finally的作用是不管这段程序是否捕获到了异常,都会执行到finally程序段,可以将系统清理工作的程序放到finally程序段中去执行。

(4)具体问题具体分析,怎么能一概而论?

     例:for(int j=0;j<50;j++){

             try{

                     …………

                    i=stmt.executeUpdate(creat sql+j+”(name char(20),type charr(20))”);

                   …………

                 }

          catch(Exception eii)

             {

                e.printStackTrace();

               continue;

             }

          }

以上程序中程序员希望在creat table报出异常时进行忽略处理,但是这个程序捕获异常用的是Exception,这就意味着所有可能发生的异常都会被捕获。也就是说,不分青红皂白的全部continue将是很可怕的事情。

(5)try里面放的程序实在是太多了。

     有些菜鸟常常喜欢把大量的代码放入单个try中,然后再用Exception去捕获异常,而不是分离各个可能出现异常的段落并分别捕获其异常,这种做法为分析程序抛出异常的原因带来了困难,因为一大段代码中有太多的地方可能抛出Exception。

(6)原封不动的将异常打印出来,为什么不考虑加点注解?

     为了让程序将捕获的异常基本完整的打印出来,可以这么做。但是当过多的异常被捕获到的时候,是否需要考虑给这些异常的打印加上注解,如果在捕获异常的打印界面中看到该异常是在何种状态下被捕获的,那么对于调试程序将是非常有帮助的。

(7)认为Exception是万能的,甚至不知道Error。

     Error是获取系统错误的类,或者说是虚拟机错误的类。不是所有的的错误Exception都能够获取到,虚拟机报错Exception是获取不到的,必须用Error获取。

14、堆和栈

堆-----用new建立,垃圾自动回收负责回收

(1)堆是一个“运行时”数据区,类实例化的对象就是从堆上去分配空间的;

(2)在堆上分配空间是通过“new”等指令建立的;

(3)Java针对堆得操作和C++的区别就是,Java不需要在空间不用的时候来显式的释放;

(4)Java的堆是由Java的垃圾回收机制来负责处理的,堆是动态分配内存大小,垃圾收集器可以自动回收不再使用的内存空间。

(5)但缺点是,因为在运行时分配内存,所以内存的存取速度较慢。

栈-------存放基本数据类型,速度快

(1)栈中主要存放一些基本类型的变量(int,long,byte,char等)和对象句柄;

(2)栈的存取速度比堆要快;

(3)栈的数据大小与生存周期必须是确定的,缺乏灵活性。

15、实例化对象的两种方法

String s = new String(“asdf”);和String s = “asdf”;

用这两种形式创建的对象是不同的,第一种是用new()来创建对象,它是在堆上开辟空间,每调用一次都会在堆上创建一个新的对象。

而第二种的创建方法则是先在栈上创建一个String类的对象引用,然后再去查找栈中有没有存放“asdf”,如果没有,则将“asdf”存放进栈,并让s指向“asdf”,如果已经有“asdf”,则直接把s指向“asdf”。

我们在比较两个String是否相等时,一定是用“equals()”方法,而当测试两个包装类的引用是否指向同一个对象时,我们应该用“==”。

例:

String s1 = “asdf”;

String s2 = “asdf”;

System.out.println(s1 == s2);

该程序运行结果是,“true”,那么说明“s1”和“s2”都是指向同一个对象的。

String s1 = new String(“asdf”);

String s2 = new String(“asdf”);

System.out.println(s1 == s2);

该程序运行的结果是“false”,这说明用new的生成方式是生成的对象,每个对象都指向不同的地方。

16、“产品”和“项目”的区别

         “产品”和“项目”的最重要的一个区别就是:是先开发再出售,还是先出售再开发。意思是说:如果卖的是产品,那么就不应该提供任何形式的定制开发业务,产品一定是先开发好的,然后再去找客户销售。

17、别指望Java和内存无关

        Java的健壮性中提到的对内存操作的安全与方便性是什么?其实只是因为Java中没有指针的概念,不需要像c++那样去delete堆上的开辟的空间,从而使程序员可以把主要精力放到程序的开发逻辑上去,从而避免了更多的开发隐患问题,虽然Java具有这个优势,但无论如何也不要指望Java和内存无关。Java提供了读取内存信息的函数:

Runtime.getRuntime().maxMemory()//得到Java虚拟机可以控制的最大内存数量

Runtime.getRuntime().totalMemory()//得到虚拟机当前已经使用的内存数量

       Java虚拟机在默认情况下只能控制63.56MB内存,那么,如何才能让Java虚拟机能够控制更多的内存呢?

可以通过非标准参数来制定JVM可以控制的堆内存的大小,只需要在Java命令后面加入一个参数—Xmx,他指定虚拟机可以控制的内存数量。

如:

18、关于内存控制的效率优化的启示

(1)String与StringBuffer的不同之处

     String这个对象实际占用内存数量与其自身的字节数不相符,应该少用String这个东西,特别是String的“+=”操作。不仅原来的String对象不能继续使用,而且又要产生多个新对象,会较高的占用内存,所以可以改用StringBuffer来实现相应的目的。

(2)用-Xmx参数来提高内存可控制量

     但扩大内存使用量永远不是最终的解决方案,如果你的程序没有去更加的优化,早晚还是会超限的。

(3)二维数组比一维数组占用更多的内存空间

     有时候我们一厢情愿的认为:二维数组的占用内存空间多无非就是二维数组的实际数组元素数比一维数组多而已,那么二维数组的所占空间一定是实际申请的元素数而已。事实上并不是这样的,他所占用的内存空间要远远大于他开辟的数组元素数。

所以在编写程序的时候要注意,能不用二维数组的地方尽量用一维数组,要求内存占用小的地方尽量用一维数组。

(3)用HashMap提高内存查询速度

      对于一个巨型的内存查询循环的时间较长的问题,Java给程序员提供了一个较快的查询方法——哈希表查询

但是HashMap在初始化以及占用内存方面都要高于普通数组,如果仅仅是为了数据存储,用普通数组是比较适合的。但如果为了频繁的查询目的,HashMap是必然的选择。

(4)用arrayCopy()提高数组截取速度

     当需要处理一个大的数组应用时,往往需要对数组进行大面积的截取与复制操作,比如针对图形显示的应用时,单纯的通过对数组元素的处理操作有时捉襟见肘,提高数组处理速度的一个很好方法是使用System.arrayCopy(),他可以提高数组的截取速度。

19、关于框架

        框架的目的是简化编程工作,框架是一个应用程序的半成品,好处是代码重用。

        框架提供了可在应用程序之间共享的可复用的公共结构。开发者把框架融入他们自己的应用程序,并加以扩展,以满足他们特定的需要,框架和工具包的不同之处在于:框架提供了一致的结构,而不仅仅是一组工具类。框架是一组组件,供你选用完成自己的系统。简单地说就是别人搭好了舞台,使用者在这个舞台上表演。

       框架不仅仅只有SSH,还有比如WebWork、EasyJWeb、Jblooming等。程序员们需要更自由的思考,就要求不仅仅局限于“框架”的“框框”中。需要像框架学习的是框架的将事物抽象的编程思想以及框架代码重用的开发理念。可以自己尝试做一个方便的框架。

20、内存垃圾回收问题

        什么是内存垃圾?

堆是一个运行时数据区,是通过new等指令建立的,Java的堆是由Java的垃圾回收机制来负责处理的。堆是动态分配内存大小,垃圾收集器可以自动回收不再使用的内存空间。也就是说,所谓的“内存垃圾”,是指在堆上开辟的内存空间在不用的时候就变成了“垃圾”。

        垃圾回收工作机制:

       垃圾收集器线程是一种低优先级的线程,他必须在一个Java程序的运行过程中出现内存空闲的时候才去回收处理;垃圾收集器系统有自己的判断内存块是否需要回收的判断标准,它不能被强制执行。虽然它是低优先级的线程,但是在系统内存可用量过低时,仍然可能会被突发地执行来挽救系统;finalize()在该对象垃圾回收前调用。对于任何给定的对象,Java虚拟机最多只调用一次finalize()方法。

       JVM使用的是分代垃圾回收方式,将内存堆分为两个区域,“新生代”和“老生代”。新生代区域中,绝大多数新创建的对象都存放在这个区域里,比区域一般来说较小而且垃圾回收频率较高,垃圾回收效率也非常高。老生代则相反。

      由于JVM在垃圾回收处理时会消耗一定的系统资源,因此有时候通过JVM启动的时候添加相关参数来控制“新生代”区域的大小,以调整垃圾回收处理的频率非常有用,这便于更合理的利用系统资源。

21、走入Java的底层程序开发

        有些程序员认为面向Web+DB的应用就是应用程序的全部,因为会误认为Serlet或structs等属于底层开发,大错特错。

        例子1.对象的序列化

        例子2.Java的动态编译

        例子3.网络应用层协议的开发(可以用socket类自己尝试用Java编写一个FTP的文件上传与下载的应用程序)

        例子4.网络七层架构的其他层的开发

        其实,没有最终的底层,最终的底层就是--网线!

        整理的这些总结中大部分自己都有切身的体会,但也有的知识点是暂时自己没有学习到的,只是整理下来,还有待于在以后的使用和接触过程中进一步加深理解。

   

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值