手记

Java中容易被你忽略的细节(四)


1.在一个程序当中代码段访问了同一个对象从单独的并发的线程当中,那么这个代码段叫”临界区”
怎么解决呢:使用同步的机制对临界区进行保护

同步的两种方式:同步块和同步方法
对于同步来说都是使用synchronized方法
每一个对象都有一个监视器,或者叫做锁。
java用监视器机制实现了进程之间的异步执行

2.Struts框架基于MVC模式
Struts的工作流程:
在web应用启动时就会加载初始化ActionServlet,ActionServlet从
struts-config.xml文件中读取配置信息,把它们存放到各种配置对象
当ActionServlet接收到一个客户请求时,将执行如下流程.
-(1)检索和用户请求匹配的ActionMapping实例,如果不存在,就返回请求路径无效信息;
-(2)如果ActionForm实例不存在,就创建一个ActionForm对象,把客户提交的表单数据保存到ActionForm对象中;
-(3)根据配置信息决定是否需要表单验证.如果需要验证,就调用ActionForm的validate()方法;
-(4)如果ActionForm的validate()方法返回或返回一个不包含ActionMessage的ActuibErrors对象, 就表示表单验证成功;
-(5)ActionServlet根据ActionMapping所包含的映射信息决定将请求转发给哪个Action,如果相应的 Action实例不存在,就先创建这个实例,然后调用Action的execute()方法;
-(6)Action的execute()方法返回一个ActionForward对象,ActionServlet在把客户请求转发给 ActionForward对象指向的JSP组件;
-(7)ActionForward对象指向JSP组件生成动态网页,返回给客户;
为什么要用:
JSP、Servlet、JavaBean技术的出现给我们构建强大的企业应用系统提供了可能。但用这些技术构建的系统非常的繁乱,所以在此之上,我们需要一个规则、一个把这些技术组织起来的规则,这就是框架,Struts便应运而生。
基于Struts开发的应用由3类组件构成:控制器组件、模型组件、视图组件

3.HttpServletRequest类主要处理:
1.读取和写入HTTP头
2.取得和设置cookies
3.读取路径信息
4.标识HTTP会话

4.== 比较的是两个对象的地址是否相同
equals 比较的是两个对象的内容是否相同
==比较的是对象的地址,也就是是否是同一个对象;
equal比较的是对象的值。

凡是new出来的就是对象
凡是new出来的就是不同的对象,无论它们长的多么相似
凡是new出来的都有自己的内存空间

5.构造方法不需要同步化。
定义在接口中的方法默认是public的。
容器保存的是对象的引用。
构造方法每次都是构造出新的对象,不存在多个线程同时读写同一对象中的属性的问题,所以不需要同步 。
如果父类中的某个方法使用了 synchronized关键字,而子类中也覆盖了这个方法,默认情况下子类中的这个方法并不是同步的,必须显示的在子类的这个方法中加上 synchronized关键字才可。当然,也可以在子类中调用父类中相应的方法,这样虽然子类中的方法并不是同步的,但子类调用了父类中的同步方法,也就相当子类方法也同步了。

6.一般关系数据模型和对象数据模型之间有以下对应关系:表对应类,记录对应对象,表的字段对应类的属性.

7.自动类型转换遵循下面的规则:
1.若参与运算的数据类型不同,则先转换成同一类型,然后进行运算。
2.转换按数据长度增加的方向进行,以保证精度不降低。例如int型和long型运算时,先把int量转成long型后再进行运算。
3.所有的浮点运算都是以双精度进行的,即使仅含float单精度量运算的表达式,也要先转换成double型,再作运算。
4.char型和short型参与运算时,必须先转换成int型。
5.在赋值运算中,赋值号两边的数据类型不同时,需要把右边表达式的类型将转换为左边变量的类型。如果右边表达式的数据类型长度比左边长时,将丢失一部分数据,这样会降低精度。
下图表示了类型自动转换的规则:
short/char--->int--->unsigned--->long---> double <---float

8.trowable 的子类 error 和 Exception
Exception 包括 非检查性异常 RuntimeException, 及其子类,即运行时的异常,运行时的异常是代码的BUG,
和检查性异常,即非运行时异常,程序在编译的时候会发现的异常 如: IOException之类,在处理类似文件流的时候,java强制规定必须处理可能遇到的文件流异常。
runtimeException是运行时的异常,在运行期间抛出异常的超类,程序可以选择是否try-catch处理。
其他的检查性异常(非运行时的异常,如IOException),是必须try-catch的,否则程序在编译的时候就会发现错误。

9.Java共有六个包装类,分别是Boolean、Character、Integer、Long、Float和Double,从字面上我们就能够看出他们分别对应于 boolean、char、int、long、float和double。而String和Date本身就是类,因此没有包装类。.

10stringbuffer与stringbuilder的区别:

  1. 在执行速度方面的比较:StringBuilder > StringBuffer
  2. StringBuffer与StringBuilder,他们是字符串变量,是可改变的对象,每当我们用它们对字符串做操作时,实际上是在一个对象上操作的,不像String一样创建一些对象进行操作,所以速度就快了。
  3. StringBuilder:线程非安全的
      StringBuffer:线程安全的
    当我们在字符串缓冲去被多个线程使用是,JVM不能保证StringBuilder的操作是安全的,虽然他的速度最快,但是可以保证StringBuffer是可以正确操作的。当然大多数情况下就是我们是在单线程下进行的操作,所以大多数情况下是建议用StringBuilder而不用StringBuffer的,就是速度的原因。

对于三者使用的总结:
1.如果要操作少量的数据用 = String
2.单线程操作字符串缓冲区下操作大量数据 = StringBuilder
3.多线程操作字符串缓冲区下操作大量数据 = StringBuffer

11.类中声明的变量有默认初始值;方法中声明的变量没有默认初始值,必须在定义时初始化,否则在访问该变量时会出错。
boolean类型默认值是false

12.不管是静态方法还是非静态方法,都需要调用后执行,其执行的次序和在类里声明的次序无关,区别是静态方法是“class.method"方式执行,非静态方法是"object.method"方式执行,即后者需要创建一个对象。
静态成员变量(也称类变量)先于非静态成员变量初始化,静态成员变量在类第一次加载时初始化,所有对象共享一份静态成员变量,非静态成员变量则在对象创建时初始化.
Java中经常有一些静态块,这是用来在生成类之前进行的初始化,无论java还C++语言中的static,都是最先初始化好的。结构如下:
static {
静态语句代码块
}

{
非静态语句代码块
}
异同点
相同点:都是在JVM加载类时且在构造方法执行之前执行,在类中都可以定义多个,一般在代码块中对一些static变量进行赋值。
不同点:静态代码块在非静态代码块之前执行(静态代码块-->非静态代码块-->构造函数)。
静态代码块只在第一次new(或者只要访问了就)执行一次,之后不在执行,而非静态代码块在每new一次都会执行一次,跟构造函数一样。非静态代码块可以在普通方法中定义(个人感觉作用不大);而静态代码块不行。

1、静态代码块是在类加载时自动执行的,非静态代码块在创建对象自动执行的代码,不创建对象不执行该类的非静态代码块。 顺序: 静态代码块--》非静态代码块--》类构造函数。
2、在静态方法里面只能直接调用同类中其他的静态成员(包括变量和方法),而不能直接访问类中的非静态成员。因为对于非静态的方法和变量,需要先创建类的实例对象后方可使用,而静态方法在使用前不用创建任何对象。
3、如果某些代码必须要在项目启动时候就执行,我们可以采用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化.

在不创建对象的情况下,其他程序来调用的时候,需要使用静态方法,此时代码是被动执行的。
区别:静态代码块是自动执行的;
静态方法是被调用的时候才执行的;
作用:静态代码块可以用来初始化一些项目最常用的变量和对象;静态方法可以用作不创建对象也可以能需要执行的代码。

13.abstract class和interface的区别:
1.抽象类可以有构造方法,接口中不能有构造方法。
2.抽象类中可以有普通成员变量,接口中没有普通成员变量。
3.一个类可以实现多个接口,但只能继承一个抽象类。
抽象类
特点:
抽象类中可以构造方法
抽象类中可以存在普通属性,方法,静态属性和方法。
抽象类中可以存在抽象方法。
如果一个类中有一个抽象方法,那么当前类一定是抽象类;抽象类中不一定有抽象方法。
抽象类中的抽象方法,需要有子类实现,如果子类不实现,则子类也需要定义为抽象的。
接口
特点:
在接口中只有方法的声明,没有方法体。
在接口中只有常量,因为定义的变量,在编译的时候都会默认加上
public static final
在接口中的方法,永远都被public来修饰。
接口中没有构造方法,也不能实例化接口的对象。
接口可以实现多继承
接口中定义的方法都需要有实现类来实现,如果实现类不能实现接口中的所有方法
则实现类定义为抽象类。

14.1.线程通过调用对象的synchronized方法可获得对象的互斥锁定。
2.线程调度算法是平台独立的。
3.通过继承Thread类或实现Runnable接口来创建线程。
线程调度分为协同式调度和抢占式调度,Java使用的是抢占式调度,也就是每个线程将由操作系统来分配执行时间,线程的切换不由线程本身来决定(协同式调度)。这就是平台独立的原因。

15.方法的重写(override)两同两小一大原则:
方法名相同,参数类型相同
子类返回类型小于等于父类方法返回类型,
子类抛出异常小于等于父类方法抛出异常,
子类访问权限大于等于父类方法访问权限。

16.1、boolean类型只有两个直接量值:true和false.
2、除成员变量会有默认初始值外,其他变量必须在第一次使用之前初始化
boolean类型的默认值是false;
其余的7种基本类型默认值:
byte是 (byte)0;
short是 (short)0;
int是 0;
long是 0L;
float 是0.0f;
double 是0.0d;
char是 \u0000;
String是null;

17.servlet中init,service,destroy方法描述:
init方法:是在servlet实例创建时调用的方法,用于创建或打开任何与servlet相关的资源和初始 化servlet的状态,Servlet规范保证调用init方法前不会处理任
何请求.init()方法是servlet生命的起点。
一旦加载了某个servlet,服务器将立即调用它的init()方法.
service方法:是servlet真正处理客户端传过来的请求的方法,由web容器调用, 根据HTTP请求方法(GET、POST等),将请求分发到doGet、doPost等方法
destory方法:是在servlet实例被销毁时由web容器调用。
Servlet规范确保在destroy方法调用之前所有请求的处理均完成,
需要覆盖destroy方法的情况:释放任何在init方法中打开的与servlet相关的资源存
储servlet的状态。destroy()方法标志servlet生命周期的结束。

18.类加载过程
类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)7个阶段。其中准备、验证、解析3个部分统称为连接(Linking)。
加载、验证、准备、初始化和卸载这5个阶段的顺序是确定的,类的加载过程必须按照这种顺序按部就班地开始,而解析阶段则不一定:它在某些情况下可以在初始化阶段之后再开始,这是为了支持Java语言的运行时绑定(也称为动态绑定或晚期绑定)。
来源:http://www.importnew.com/18548.html

19.java不允许单独的方法,过程或函数存在,需要隶属于某一类中。
java语言中的方法属于对象的成员,而不是类的成员。不过,其中静态方法属于类的成员。
Java语言中的方法必定隶属于某一类(对象),调用方法与过程或函数相同。

20.Java 提供的事件处理模型是一种人机交互模型。它有三个基本要素:
1) 事件源(Event Source):即事件发生的场所,就是指各个组件,如按钮等,点击按钮其实就是组件上发生的一个事件;
2) 事件(Event):事件封装了组件上发生的事情,比如按钮单击、按钮松开等等;
3) 事件监听器(Event Listener):负责监听事件源上发生的特定类型的事件,当事件到来时还必须负责处理相应的事件;

3人推荐
随时随地看视频
慕课网APP

热门评论

你确定不是八个包装类

查看全部评论