仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 1450|回复: 20
打印 上一主题 下一主题

[学习教程] JAVA教程之详解Java中的指针、援用及对象的clone

[复制链接]
精灵巫婆 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-18 11:54:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
最后就是我对java的几点希望:首先是IDE工具,有人说java已经很好了,有jbuilder,eclipse,netBeans等等,但是我认为如果java想超越.net,那么他首先要解决的就是IDE工具的整合。对象|详解Java言语的一个长处就是作废了指针的观点,但也招致了很多程序员在编程中经常疏忽了对象与援用的区分,本文会试图廓清这一观点。而且因为Java不克不及经由过程复杂的赋值来办理对象复制的成绩,在开辟过程当中,也经常要要使用clone()办法来复制对象。本文会让你懂得甚么是影子clone与深度clone,熟悉它们的区分、长处及弱点。看到这个题目,是否是有点狐疑:Java言语明白申明作废了指针,由于指针常常是在带来便利的同时也是招致代码不平安的本源,同时也会使程序的变得十分庞大难以了解,滥用指针写成的代码不亚于利用早已臭名远扬的"GOTO"语句。Java保持指针的观点相对是极为明智的。但这只是在Java言语中没有明白的指针界说,本色上每个new语句前往的都是一个指针的援用,只不外在年夜多时分Java中不必体贴怎样操纵这个"指针",更不必象在操纵C++的指针那样人心惶惶。独一要多多体贴的是在给函数传送对象的时分。以下例程:
packagereference;
classObj
{
Stringstr="initvalue";
publicStringtoString()
{
returnstr;
}
}
publicclassObjRef
{
ObjaObj=newObj();
intaInt=11;
publicvoidchangeObj(ObjinObj)
{
inObj.str="changedvalue";
}
publicvoidchangePri(intinInt)
{
inInt=22;
}
publicstaticvoid
main(String[]args)
{
ObjRefoRef=newObjRef();System.out.println("Beforecall
changeObj()method:
"+oRef.aObj);
oRef.changeObj(oRef.aObj);
System.out.println
("AftercallchangeObj()
method:"+oRef.aObj);System.out.println
("==================PrintPrimtive=================");
System.out.println("Beforecall
changePri()method:"+oRef.aInt);
oRef.changePri(oRef.aInt);
System.out.println("Aftercall
changePri()method:"+oRef.aInt);}
}/*RUNRESULT
BeforecallchangeObj()method:
initvalue
AftercallchangeObj()method:
changedvalue
==================PrintPrimtive=================
BeforecallchangePri()method:11
AftercallchangePri()method:11*
*/
这段代码的次要部分挪用了两个很邻近的办法,changeObj()和changePri()。独一分歧的是它们一个把对象作为输出参数,另外一个把Java中的基础范例int作为输出参数。而且在这两个函数体外部都对输出的参数举行了修改。看似一样的办法,程序输入的了局却不太一样。changeObj()办法真实的把输出的参数改动了,而changePri()办法对输出的参数没有任何的改动。从这个例子晓得Java对对象和基础的数据范例的处置是纷歧样的。和C言语一样,当把Java的基础数据范例(如int,char,double等)作为出口参数传给函数体的时分,传进的参数在函数体外部酿成下场部变量,这个部分变量是输出参数的一个拷贝,一切的函数体外部的操纵都是针对这个拷贝的操纵,函数实行停止后,这个部分变量也就完成了它的任务,它影响不到作为输出参数的变量。这类体例的参数传送被称为"值传送"。而在Java顶用对象的作为出口参数的传送则缺省为"援用传送",也就是说仅仅传送了对象的一个"援用",这个"援用"的观点同C言语中的指针援用是一样的。当函数体外部对输出变量改动时,本色上就是在对这个对象的间接操纵。除在函数传值的时分是"援用传送",在任何用"="向对象变量赋值的时分都是"援用传送"。如:
packagereference;
classPassObj
{
Stringstr="initvalue";
}
publicclassObjPassvalue
{publicstaticvoid
main(String[]args)
{
PassObjobjA=newPassObj();
PassObjobjB=objA;objA.str="changedinobjA";
System.out.println
("PrintobjB.strvalue:
"+objB.str);
}
}
/*RUNRESULT
PrintobjB.strvalue:
changedinobjA
*/
第一句是在内存中天生一个新的PassObj对象,然后把这个PassObj的援用赋给变量objA,第二句是把PassObj对象的援用又赋给了变量objB。此时objA和objB是两个完整分歧的变量,今后任何对objA的改动都同等于对objB的改动。即便分明了Java言语中的"指针"观点大概还会不经意间犯上面的毛病。Hashtable真的能存储对象吗?看一看上面的很复杂的代码,先是声了然一个Hashtable和StringBuffer对象,然后分四次把StriingBuffer对象放进到Hashtable表中,在每次放进之前都对这个StringBuffer对象append()了一些新的字符串:
packagereference;
importjava.util.*;
publicclassHashtableAdd{
publicstaticvoid
main(String[]args){
Hashtableht=newHashtable();
StringBuffersb=
newStringBuffer();
sb.append("abc,");
ht.put("1",sb);
sb.append("def,");
ht.put("2",sb);
sb.append("mno,");
ht.put("3",sb);
sb.append("xyz.");
ht.put("4",sb);intnumObj=0;
Enumerationit=ht.elements();
while(it.hasMoreElements())
{
System.out.print("getStringBufffer
"+(++numObj)+"fromHashtable:");
System.out.println(it.nextElement());
}
}
}
假如你以为输入的了局是:
getStringBufffer1
fromHashtable:abc,
getStringBufffer2
fromHashtable:abc,def,
getStringBufffer3
fromHashtable:abc,def,mno,
getStringBufffer4
fromHashtable:abc,def,mno,xyz.
那末你就要回过火再细心看一看上一个成绩了,把对象时作为出口参数传给函数,本色上是传送了对象的援用,向Hashtable传送StringBuffer对象也是只传送了这个StringBuffer对象的援用。每次向Hashtable表中put一次StringBuffer,并没有天生新的StringBuffer对象,只是在Hashtable表中又放进了一个指向统一StringBuffer对象的援用罢了。对Hashtable表存储的任何一个StringBuffer对象(更切实的说应当是对象的援用)的修改,实践上都是对统一个"StringBuffer"的修改。以是Hashtable其实不能真正存储能对象,而只能存储对象的援用。也应当晓得这条准绳对与Hashtable类似的Vector,List,Map,Set等都是一样的。下面的例程的实践输入的了局是:
/*RUNRESULT
getStringBufffer1
fromHashtable:abc,def,mno,xyz.
getStringBufffer2
fromHashtable:abc,def,mno,xyz.
getStringBufffer3
fromHashtable:abc,def,mno,xyz.
getStringBufffer4
fromHashtable:abc,def,mno,xyz.
*/
类,对象与援用Java最基础的观点就是类,类包含函数和变量。假如想要使用类,就要把类天生对象,这个历程被称作"类的实例化"。有几种办法把类实例化成对象,最经常使用的就是用"new"操纵符。类实例化成对象后,就意味着要在内存中占有一块空间寄存实例。想要对这块空间操纵就要使用到对象的援用。援用在Java言语中的表现就是变量,而变量的范例就是这个援用的对象。固然在语法上能够在天生一个对象后间接挪用该对象的函数或变量,如:
newString("HelloNDP")).substring(0,3)
  //RETURNRESULT:Hel
但因为没有响应的援用,对这个对象的利用也只能范围这条语句中了。发生:援用老是在把对象作参数"传送"的过程当中主动产生,不必要工资的发生,也不克不及工资的把持援用的发生。这个传送包含把对象作为函数的出口参数的情形,也包含用"="举行对象赋值的时分。局限:只要部分的援用,没有部分的对象。援用在Java言语的表现就是变量,而变量在Java言语中是有局限的,能够是部分的,也能够是全局的。保存期:程序只能把持援用的保存周期。对象的保存期是由Java把持。用"newObject()"语句天生一个新的对象,是在盘算机的内存中声明一块地区存储对象,只要Java的渣滓搜集器才干决意在得当的时分接纳对象占用的内存。没有举措制止对援用的修改。甚么是"clone"?在实践编程过程当中,我们经常要碰到这类情形:有一个对象A,在某一时候A中已包括了一些无效值,此时大概会必要一个和A完整不异新对象B,而且今后对B任何修改都不会影响到A中的值,也就是说,A与B是两个自力的对象,但B的初始值是由A对象断定的。在Java言语中,用复杂的赋值语句是不克不及满意这类需求的。要满意这类需求固然有良多路子,但完成clone()办法是个中最复杂,也是最高效的手腕。Java的一切类都默许承继java.lang.Object类,在java.lang.Object类中有一个办法clone()。JDKAPI的申明文档注释这个办法将前往Object对象的一个拷贝。要申明的有两点:一是拷贝对象前往的是一个新对象,而不是一个援用。二是拷贝对象与用new操纵符前往的新对象的区分就是这个拷贝已包括了一些本来对象的信息,而不是对象的初始信息。如何使用clone()办法?一个很典范的挪用clone()代码以下:
classCloneClass
implementsCloneable
{
publicintaInt;
publicObjectclone()
{
CloneClasso=null;
try{
o=(CloneClass)super.clone();
}catch(CloneNotSupportedExceptione)
{
e.printStackTrace();
}
returno;
}

有三个值得注重的中央,一是但愿能完成clone功效的CloneClass类完成了Cloneable接口,这个接口属于java.lang包,java.lang包已被缺省的导进类中,以是不必要写成java.lang.Cloneable。另外一个值得请注重的是重载了clone()办法。最初在clone()办法中挪用了super.clone(),这也意味着不管clone类的承继布局是甚么样的,super.clone()间接或直接挪用了java.lang.Object类的clone()办法。上面再具体的注释一下这几点。应当说第三点是最主要的,细心察看一下Object类的clone()一个native办法,native办法的效力一样平常来讲都是远高于java中的非native办法。这也注释了为何要用Object中clone()办法而不是先new一个类,然后把原始对象中的信息赋到新对象中,固然这也完成了clone功效。关于第二点,也要察看Object类中的clone()仍是一个protected属性的办法。这也意味着假如要使用clone()办法,必需承继Object类,在Java中一切的类是缺省承继Object类的,也就不必体贴这点了。然后重载clone()办法。另有一点要思索的是为了让别的类能挪用这个clone类的clone()办法,重载以后要把clone()办法的属性设置为public。那末clone类为何还要完成Cloneable接口呢?略微注重一下,Cloneable接口是不包括任何办法的!实在这个接口仅仅是一个标记,并且这个标记也仅仅是针对Object类中clone()办法的,假如clone类没有完成Cloneable接口,并挪用了Object的clone()办法(也就是挪用了super.Clone()办法),那末Object的clone()办法就会抛出CloneNotSupportedException非常。以上是clone的最基础的步骤,想要完成一个乐成的clone,还要懂得甚么是"影子clone"和"深度clone"。甚么是影子clone?上面的例子包括三个类UnCloneA,CloneB,CloneMain。CloneB类包括了一个UnCloneA的实例和一个int范例变量,而且重载clone()办法。CloneMain类初始化UnCloneA类的一个实例b1,然后挪用clone()办法天生了一个b1的拷贝b2。最初考查一下b1和b2的输入:
packageclone;
classUnCloneA{
privateinti;
publicUnCloneA(intii){i=ii;}
publicvoiddoublevalue(){i*=2;}
publicStringtoString(){
returnInteger.toString(i);
}
}
classCloneBimplementsCloneable{
publicintaInt;
publicUnCloneAunCA=newUnCloneA(111);
publicObjectclone(){
CloneBo=null;
try{
o=(CloneB)super.clone();
}catch(CloneNotSupportedExceptione){
e.printStackTrace();
}
returno;
}
}
publicclassCloneMain{
publicstaticvoidmain(String[]a){
CloneBb1=newCloneB();
b1.aInt=11;
System.out.println("before
clone,b1.aInt="+b1.aInt);
System.out.println("before
clone,b1.unCA="+b1.unCA);CloneBb2=(CloneB)b1.clone();
b2.aInt=22;
b2.unCA.doublevalue();
System.out.println("=================================");
System.out.println("afterclone,b1.aInt="+b1.aInt);
System.out.println("afterclone,b1.unCA="+b1.unCA);
System.out.println("=================================");
System.out.println("afterclone,b2.aInt="+b2.aInt);
System.out.println("afterclone,b2.unCA="+b2.unCA);
}
}
/**RUNRESULT:
beforeclone,b1.aInt=11
beforeclone,b1.unCA=111
=================================
afterclone,b1.aInt=11
afterclone,b1.unCA=222
=================================
afterclone,b2.aInt=22
afterclone,b2.unCA=222
*/
输入的了局申明int范例的变量aInt和UnCloneA的实例对象unCA的clone了局纷歧致,int范例是真实的被clone了,由于改动了b2中的aInt变量,对b1的aInt没有发生影响,也就是说,b2.aInt与b1.aInt已占有了分歧的内存空间,b2.aInt是b1.aInt的一个真正拷贝。相反,对b2.unCA的改动同时改动了b1.unCA,很分明,b2.unCA和b1.unCA是仅仅指向统一个对象的分歧援用!从中能够看出,挪用Object类中clone()办法发生的效果是:先在内存中启示一块和原始对象一样的空间,然后原样拷贝原始对象中的内容。对基础数据范例,如许的操纵是没有成绩的,但对非基础范例变量,我们晓得它们保留的仅仅是对象的援用,这也招致clone后的非基础范例变量和原始对象中响应的变量指向的是统一个对象。年夜多时分,这类clone的了局常常不是我们所但愿的了局,这类clone也被称为"影子clone"。要想让b2.unCA指向与b2.unCA分歧的对象,并且b2.unCA中还要包括b1.unCA中的信息作为初始信息,就要完成深度clone。怎样举行深度clone?把下面的例子改成深度clone很复杂,必要两个改动:一是让UnCloneA类也完成和CloneB类一样的clone功效(完成Cloneable接口,重载clone()办法)。二是在CloneB的clone()办法中到场一句:o.unCA=(UnCloneA)unCA.clone();
程序以下:
packageclone.ext;
classUnCloneAimplementsCloneable{
privateinti;
publicUnCloneA(intii){i=ii;}
publicvoiddoublevalue(){i*=2;}
publicStringtoString(){
returnInteger.toString(i);
}
publicObjectclone(){
UnCloneAo=null;
try{
o=(UnCloneA)super.clone();
}catch(CloneNotSupportedExceptione){
e.printStackTrace();
}
returno;
}
}
classCloneBimplementsCloneable{
publicintaInt;
publicUnCloneAunCA=newUnCloneA(111);
publicObjectclone(){
CloneBo=null;
try{
o=(CloneB)super.clone();
}catch(CloneNotSupportedExceptione){
e.printStackTrace();
}
o.unCA=(UnCloneA)unCA.clone();
returno;
}
}
publicclassCloneMain{
publicstaticvoidmain(String[]a){
CloneBb1=newCloneB();
b1.aInt=11;
System.out.println("before
clone,b1.aInt="+b1.aInt);
System.out.println("before
clone,b1.unCA="+b1.unCA);CloneBb2=(CloneB)b1.clone();
b2.aInt=22;
b2.unCA.doublevalue();
System.out.println("=================================");
System.out.println("afterclone,b1.aInt="+b1.aInt);
System.out.println("afterclone,b1.unCA="+b1.unCA);
System.out.println("=================================");
System.out.println("afterclone,b2.aInt="+b2.aInt);
System.out.println("afterclone,b2.unCA="+b2.unCA);
}
}/**RUNRESULT:
beforeclone,b1.aInt=11
beforeclone,b1.unCA=111
=================================
afterclone,b1.aInt=11
afterclone,b1.unCA=111
=================================
afterclone,b2.aInt=22
afterclone,b2.unCA=222
*/
能够看出,如今b2.unCA的改动对b1.unCA没有发生影响。此时b1.unCA与b2.unCA指向了两个分歧的UnCloneA实例,并且在CloneBb2=(CloneB)b1.clone();挪用的那一刻b1和b2具有不异的值,在这里,b1.i=b2.i=11。要晓得不是一切的类都能完成深度clone的。比方,假如把下面的CloneB类中的UnCloneA范例变量改成StringBuffer范例,看一下JDKAPI中关于StringBuffer的申明,StringBuffer没有重载clone()办法,更加严峻的是StringBuffer仍是一个final类,这也是说我们也不克不及用承继的举措直接完成StringBuffer的clone。假如一个类中包括有StringBuffer范例对象或和StringBuffer类似类的对象,我们有两种选择:要末只能完成影子clone,要末就在类的clone()办法中加一句(假定是SringBuffer对象,并且变量名还是unCA):
o.unCA=newStringBuffer
(unCA.toString());
//本来的是:
o.unCA=(UnCloneA)unCA.clone();
还要晓得的是除基础数据范例能主动完成深度clone之外,String对象是一个破例,它clone后的体现好象也完成了深度clone,固然这只是一个假象,但却年夜小气便了我们的编程。Clone中String和StringBuffer的区分应当申明的是,这里不是侧重申明String和StringBuffer的区分,但从这个例子里也能看出String类的一些不同凡响的中央。上面的例子中包含两个类,CloneC类包括一个String范例变量和一个StringBuffer范例变量,而且完成了clone()办法。在StrClone类中声了然CloneC范例变量c1,然后挪用c1的clone()办法天生c1的拷贝c2,在对c2中的String和StringBuffer范例变量用响应的办法修改以后打印了局:
packageclone;
classCloneCimplementsCloneable{
publicStringstr;
publicStringBufferstrBuff;
publicObjectclone(){
CloneCo=null;
try{
o=(CloneC)super.clone();
}catch(CloneNotSupportedExceptione){
e.printStackTrace();
}
returno;
}}
publicclassStrClone{
publicstaticvoidmain(String[]a)
{
CloneCc1=newCloneC();
c1.str=newString("initializeStr");
c1.strBuff=newStringBuffer
("initializeStrBuff");
System.out.println("before
clone,c1.str="+c1.str);
System.out.println("before
clone,c1.strBuff="+c1.strBuff);CloneCc2=(CloneC)c1.clone();
c2.str=c2.str.substring(0,5);
c2.strBuff=c2.strBuff.append
("changestrBuffclone");
System.out.println("=================================");
System.out.println("after
clone,c1.str="+c1.str);
System.out.println
("afterclone,c1.strBuff="+c1.strBuff);
System.out.println("=================================");
System.out.println("after
clone,c2.str="+c2.str);
System.out.println
("afterclone,c2.strBuff="+c2.strBuff);
}
}
/*RUNRESULT
beforeclone,c1.str=initializeStr
beforeclone,c1.strBuff=initializeStrBuff
=================================
afterclone,c1.str=initializeStr
afterclone,c1.strBuff=
initializeStrBuffchangestrBuffclone
=================================
afterclone,c2.str=initi
afterclone,c2.strBuff=
initializeStrBuffchangestrBuffclone
*
*/
打印的了局能够看出,String范例的变量好象已完成了深度clone,由于对c2.str的修改并没有影响到c1.str!岂非Java把Sring类当作了基础数据范例?实在否则,这里有一个小小的幻术,奥密就在于c2.str=c2.str.substring(0,5)这一语句。本色上,在clone的时分c1.str与c2.str仍旧是援用,并且都指向了统一个String对象。但在实行c2.str=c2.str.substring(0,5)的时分,它感化相称于天生了一个新的String范例,然后又赋回给c2.str。这是由于String被Sun公司的工程师写成了一个不成变动的类(immutableclass),在一切String类中的函数都不克不及变动本身的值。上面给出很复杂的一个例子:
packageclone;publicclassStrTest
{
publicstaticvoidmain(String[]args)
{
Stringstr1="Thisisatestforimmutable";
Stringstr2=str1.substring(0,8);
System.out.println("printstr1:"+str1);
System.out.println("printstr2:"+str2);
}
}
/*RUNRESULTprintstr1:
Thisisatestforimmutableprintstr2:
Thisis*/
例子中,固然str1挪用了substring()办法,但str1的值并没有改动。相似的,String类中的别的办法也是云云。固然假如我们把最下面的例子中的这两条语句
c2.str=c2.str.substring(0,5);
c2.strBuff=c2.strBuff.append
("changestrBuffclone");
改成上面如许:
c2.str.substring(0,5);
c2.strBuff.append
("changestrBuffclone");
往失落了从头赋值的历程,c2.str也就不克不及有变更了,我们的幻术也就露馅了。但在编程过程当中只挪用
c2.str.substring(0,5);
语句是没有任何意义的。应当晓得的是在Java中一切的基础数据范例都有一个绝对应的类,象Integer类对应int范例,Double类对应double范例等等,这些类也与String类不异,都是不成以改动的类。也就是说,这些的类中的一切办法都是不克不及改动其本身的值的。这也让我们在编clone类的时分有了一个更多的选择。同时我们也能够把本人的类编成不成变动的类。
轮性能微软曾做过一个例子,就是同一个项目用java和.net来作,结果开发周期,.net是java的一半,性能java是.net的十分之一,代码量java是.net的三倍。呵呵,这说明了什么,.net的全方位比java好。但是有的人说.net不能跨平台,这个问题我和我同学曾讨论过,都认为微软的.net很可能早都可以跨平台了,但是微软为了保护他们的操作系统,所以才没有推出跨平台的.net,只是推出了跨语言的.net,
admin 该用户已被删除
沙发
发表于 2015-1-21 16:57:16 | 只看该作者
你一定会高兴地说,哈哈,原来成为Java高手就这么简单啊!记得Tomjava也曾碰到过一个项目经理,号称Java很简单,只要三个月就可以学会。
变相怪杰 该用户已被删除
板凳
发表于 2015-1-21 21:27:23 | 只看该作者
Java是一种计算机编程语言,拥有跨平台、面向对java
蒙在股里 该用户已被删除
地板
发表于 2015-1-30 22:33:28 | 只看该作者
自从Sun推出Java以来,就力图使之无所不包,所以Java发展到现在,按应用来分主要分为三大块:J2SE,J2ME和J2EE,这也就是Sun ONE(Open Net Environment)体系。J2SE就是Java2的标准版,主要用于桌面应用软件的编程;J2ME主要应用于嵌入是系统开发,如手机和PDA的编程;J2EE是Java2的企业版,主要用于分布式的网络程序的开发,如电子商务网站和ERP系统。
老尸 该用户已被删除
5#
发表于 2015-2-4 20:07:02 | 只看该作者
多重继承(以接口取代)等特性,增加了垃圾回收器功能用于回收不再被引用的对象所占据的内存空间,使得程序员不用再为内存管理而担忧。在 Java 1.5 版本中,Java 又引入了泛型编程(Generic Programming)、类型安全的枚举、不定长参数和自动装/拆箱等语言特性。
乐观 该用户已被删除
6#
发表于 2015-2-4 21:15:56 | 只看该作者
其实说这种话的人就如当年小日本号称“三个月拿下中国”一样大言不惭。不是Tomjava泼你冷水,你现在只是学到了Java的骨架,却还没有学到Java的精髓。接下来你得研究设计模式了。
只想知道 该用户已被删除
7#
发表于 2015-2-10 11:33:14 | 只看该作者
吧,现在很流行的Structs就是它的一种实现方式,不过Structs用起来实在是很繁,我们只要学习其精髓即可,我们完全可以设计自己的MVC结构。然后你再研究一下软件Refactoring (重构)和极限XP编程,相信你又会上一个台阶。 做完这些,你不如整理一下你的Java代码,把那些经典的程序和常见的应用整理出来,再精心打造一番,提高其重用性和可扩展性。你再找几个志同道合的朋友成立一个工作室吧
8#
发表于 2015-2-28 18:37:38 | 只看该作者
你就该学一学Servlet了。Servlet就是服务器端小程序,他负责生成发送给客户端的HTML文件。JSP在执行时,也是先转换成Servlet再运行的。虽说JSP理论上可以完全取代Servlet,这也是SUN推出JSP的本意,可是Servlet用来控制流程跳转还是挺方便的,也令程序更清晰。接下来你应该学习一下Javabean了,可能你早就看不管JSP在HTML中嵌Java代码的混乱方式了,这种方式跟ASP又有什么区别呢?
第二个灵魂 该用户已被删除
9#
发表于 2015-3-3 03:29:00 | 只看该作者
是一种使网页(Web Page)由静态(Static)转变为动态(Dynamic)的语言
深爱那片海 该用户已被删除
10#
发表于 2015-3-4 18:16:51 | 只看该作者
关于设计模式的资料,还是向大家推荐banq的网站 [url]http://www.jdon.com/[/url],他把GOF的23种模式以通俗易懂的方式诠释出来,纯Java描述,真是经典中的经典。
简单生活 该用户已被删除
11#
发表于 2015-3-6 16:39:52 | 只看该作者
J2SE开发桌面应用软件比起 VC,VB,DEPHI这些传统开发语言来说,优势好象并不明显。J2ME对于初学者来说,好象又有点深奥,而且一般开发者很难有开发环境。
爱飞 该用户已被删除
12#
发表于 2015-3-7 09:51:21 | 只看该作者
所以现在应用最广泛又最好学的就是J2EE了。 J2EE又包括许多组件,如Jsp,Servlet,JavaBean,EJB,JDBC,JavaMail等。要学习起来可不是一两天的事。那么又该如何学习J2EE呢?当然Java语法得先看一看的,I/O包,Util包,Lang包你都熟悉了吗?然后再从JSP学起。
山那边是海 该用户已被删除
13#
发表于 2015-3-14 18:24:11 | 只看该作者
如果要向java web方向发展也要吧看看《Java web从入门到精通》学完再到《Struts2.0入门到精通》这样你差不多就把代码给学完了。有兴趣可以看一些设计模块和框架的包等等。
再现理想 该用户已被删除
14#
发表于 2015-3-14 18:29:31 | 只看该作者
你可以去承接一些项目做了,一开始可能有些困难,可是你有技术积累,又考虑周全,接下项目来可以迅速作完,相信大家以后都会来找你的,所以Money就哗啦啦的。。。。。。
海妖 该用户已被删除
15#
发表于 2015-3-21 12:36:27 | 只看该作者
还好,SUN提供了Javabean可以把你的JSP中的 Java代码封装起来,便于调用也便于重用。
透明 该用户已被删除
16#
发表于 2015-3-23 03:49:59 | 只看该作者
Sun公司看见Oak在互联网上应用的前景,于是改造了Oak,于1995年5月以Java的名称正式发布。Java伴随着互联网的迅猛发展而发展,逐渐成为重要的网络编程语言。
活着的死人 该用户已被删除
17#
发表于 2015-3-25 15:22:36 | 只看该作者
是一种使用者不需花费很多时间学习的语言
因胸联盟 该用户已被删除
18#
发表于 2015-3-27 09:07:23 | 只看该作者
是一种突破用户端机器环境和CPU
不帅 该用户已被删除
19#
发表于 2015-3-31 12:50:37 | 只看该作者
Sun公司看见Oak在互联网上应用的前景,于是改造了Oak,于1995年5月以Java的名称正式发布。Java伴随着互联网的迅猛发展而发展,逐渐成为重要的网络编程语言。
兰色精灵 该用户已被删除
20#
发表于 2015-4-11 01:11:27 | 只看该作者
Java自面世后就非常流行,发展迅速,对C++语言形成了有力冲击。Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于个人PC、数据中心、游戏控制台
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-11-15 22:23

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表