码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2016-12-29 23:35:20      阅读:344      评论:0      收藏:0      [点我收藏+]

标签: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):负责监听事件源上发生的特定类型的事件,当事件到来时还必须负责处理相应的事件;


21.在WEB开发中实现会话跟踪的技术有:session,cookie,地址重写,隐藏域。

1.Cookies

      Cookies是使用最广泛的会话跟踪机制,Cookies是有服务器创建,并把Cookies信息保存在用户机器上的硬盘上,下次用户再次访问该站点服 务器的时候,保存在用户机器上硬盘的Cookies信息就被送回给服务器。一般Cookies一般不多于4KB,且用户的敏感信息如信用卡账号密码不应该 保存在Cookies中。

2.URL重写

       URL重用户在每个URL结尾附加标识回话的数据,与标识符关联的服务器保存有关与会话的数据,如我们访问某个新闻的时候,在地址栏我们一般会看到这样的 信息:http://www.XXX.com/news?id=??,通常的话id后面的问号表示该条新闻在后台数据库中的新闻表的id。URL重写能够 在客户端停用cookies或者不支持cookies的时候仍然能够发挥作用。

3.隐藏表单域

      通常,在表单中我们使用隐藏表单域的时候会有这么一句代码:<input type=”hidden” name=”XXX”  value=”XXX”/>。通过给type属性赋值为hidden值来实现隐藏,这样用户在浏览的时候看不到这行代码的数据,但是当用户通过查看 源代码还是可以看到的。

4.Session机制

       这个机制要慎用,特别是对于访问量很大的站点,因为这种机制是吧Session信息保存在服务器端。如果访问量特别大的话,对于服务器的承受力的要求有多高是可想而知的。


Cookie(结合session使用)

可以使用 cookie 存储购物会话的 ID;在后续连接中,取出当前的会话 ID,并使用这个 ID 从服务器上的查找表(lookup table)中提取出会话的相关信息。 以这种方式使用 cookie 是一种绝佳的解决方案,也是在处理会话时最常使用的方式。但是,sevlet 中最好有一种高级的 API 来处理所有这些任务,以及下面这些冗长乏味的任务:从众多的其他cookie中(毕竟可能会存在许多cookie)提取出存储会话标识符的 cookie;确定空闲会话什么时候过期,并回收它们;将散列表与每个请求关联起来;生成惟一的会话标识符。

URL 重写

采用这种方式时,客户程序在每个URL的尾部添加一些额外数据。这些数据标识当前的会话,服务器将这个标识符与它存储的用户相关数据关联起来。 URL重写是比较不错的会话跟踪解决方案,即使浏览器不支持 cookie 或在用户禁用 cookie 的情况下,这种方案也能够工作。URL 重写具有 cookie 所具有的同样缺点,也就是说,服务器端程序要做许多简单但是冗长乏味的处理任务。即使有高层的 API 可以处理大部分的细节,仍须十分小心每个引用你的站点的 URL ,以及那些返回给用户的 URL。即使通过间接手段,比如服务器重定向中的 Location 字段,都要添加额外的信息。这种限制意味着,在你的站点上不能有任何静态 HTML 页面(至少静态页面中不能有任何链接到站点动态页面的链接)。因此,每个页面都必须使用 servlet 或 JSP 动态生成。即使所有的页面都动态生成,如果用户离开了会话并通过书签或链接再次回来,会话的信息也会丢失,因为存储下来的链接含有错误的标识信息。

隐藏的表单域

HTML 表单中可以含有如下的条目:<input type="hidden" name="session" value="a1234">

这个条目的意思是:在提交表单时,要将指定的名称和值自动包括在 GET 或 POST 数据中。这个隐藏域可以用来存储有关会话的信息,但它的主要缺点是:仅当每个页面都是由表单提交而动态生成时,才能使用这种方法。单击常规的超文本链接并不产生表单提交,因此隐藏的表单域不能支持通常的会话跟踪,只能用于一系列特定的操作中,比如在线商店的结账过程。


本文出自 “学虽易学好难且学且珍惜” 博客,请务必保留此出处http://lhf20132175.blog.51cto.com/11029145/1887490

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

标签:java

原文地址:http://lhf20132175.blog.51cto.com/11029145/1887490

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!