??xml version="1.0" encoding="utf-8" standalone="yes"?>
----对这两个概念的不明好久,l于扑ֈ一好文,拿来׃nQhttp://www.duduwolf.com/cmd.asp?act=tb&id=3 Q?/p>
1. ?stack)与堆(heap)都是Java用来在Ram中存放数据的地方。与C++不同QJava自动理栈和堆,E序员不能直接地讄栈或堆?
2. 栈的优势是,存取速度比堆要快Q仅ơ于直接位于CPU中的寄存器。但~点是,存在栈中的数据大与生存期必L定的,~Z灉|性。另外,栈数据可以共享,详见W?炏V堆的优势是可以动态地分配内存大小Q生存期也不必事先告诉编译器QJava的垃圾收集器会自动收走这些不再用的数据。但~点是,׃要在q行时动态分配内存,存取速度较慢?/p>
3. Java中的数据cd有两U?/p>
一U是基本cd(primitive types), 共有8U,即int, short, long, byte, float, double, boolean, char(注意Qƈ没有string的基本类?。这U类型的定义是通过诸如int a = 3; long b = 255L;的Ş式来定义的,UCؓ自动变量。值得注意的是Q自动变量存的是字面|不是cȝ实例Q即不是cȝ引用Q这里ƈ没有cȝ存在。如int a = 3; q里的a是一个指向intcd的引用,指向3q个字面倹{这些字面值的数据Q由于大可知,生存期可?q些字面值固定定义在某个E序块里面,E序块退出后Q字D值就消失?Q出于追求速度的原因,存在于栈中?/p>
另外Q栈有一个很重要的特D性,是存在栈中的数据可以共享。假设我们同时定义:
int a = 3 ;
int b = 3Q?/span>
特别注意的是Q这U字面值的引用与类对象的引用不同。假定两个类对象的引用同时指向一个对象,如果一个对象引用变量修改了q个对象的内部状态,那么另一个对象引用变量也卛_反映个变化。相反,通过字面值的引用来修改其|不会D另一个指向此字面值的引用的g跟着改变的情c如上例Q我们定义完a与b的值后Q再令a=4Q那么,b不会{于4Q还是等?。在~译器内部,遇到a=4Q时Q它׃重新搜烦栈中是否?的字面|如果没有Q重新开辟地址存放4的|如果已经有了Q则直接a指向q个地址。因此a值的改变不会影响到b的倹{?/p>
另一U是包装cL据,如Integer, String, Double{将相应的基本数据类型包装v来的cR这些类数据全部存在于堆中,Java用new()语句来显C地告诉~译器,在运行时才根据需要动态创建,因此比较灉|Q但~点是要占用更多的时间?4. String是一个特D的包装cL据。即可以用String str = new String("abc");的Ş式来创徏Q也可以用String str = "abc"Q的形式来创?作ؓҎQ在JDK 5.0之前Q你从未见过Integer i = 3;的表辑ּQ因为类与字面值是不能通用的,除了String。而在JDK 5.0中,q种表达式是可以的!因ؓ~译器在后台q行Integer i = new Integer(3)的{?。前者是规范的类的创E,卛_Java中,一切都是对象,而对象是cȝ实例Q全部通过new()的Ş式来创徏。Java中的有些c,如DateFormatc,可以通过该类的getInstance()Ҏ来返回一个新创徏的类Q似乎违反了此原则。其实不然。该c运用了单例模式来返回类的实例,只不q这个实例是在该cd部通过new()来创建的Q而getInstance()向外部隐藏了此细节。那Z么在String str = "abc"Q中Qƈ没有通过new()来创建实例,是不是违反了上述原则Q其实没有?/p>
5. 关于String str = "abc"的内部工作。Java内部此语句转化Z下几个步骤:
(1)先定义一个名为str的对Stringcȝ对象引用变量QString strQ?/p>
(2)在栈中查找有没有存放gؓ"abc"的地址Q如果没有,则开辟一个存攑֭面gؓ"abc"的地址Q接着创徏一个新的Stringcȝ对象oQƈo的字W串值指向这个地址Q而且在栈中这个地址旁边Cq个引用的对象o。如果已l有了gؓ"abc"的地址Q则查找对象oQƈq回o的地址?/p>
(3)str指向对象o的地址?/p>
值得注意的是Q一般StringcM字符串值都是直接存值的。但像String str = "abc"Q这U场合下Q其字符串值却是保存了一个指向存在栈中数据的引用Q?/p>
Z更好地说明这个问题,我们可以通过以下的几个代码进行验证?/p>
Stringstr1="abc";
Stringstr2="abc";
System.out.println(str1==str2);//true
我们再来更进一步,以上代码改成:
Stringstr1="abc";
Stringstr2="abc";
str1="bcd";
System.out.println(str1+","+str2);//bcd,abc
System.out.println(str1==str2);//false
q就是说Q赋值的变化D了类对象引用的变化,str1指向了另外一个新对象Q而str2仍旧指向原来的对象。上例中Q当我们str1的值改?bcd"ӞJVM发现在栈中没有存放该值的地址Q便开辟了q个地址Qƈ创徏了一个新的对象,其字W串的值指向这个地址?/p>
事实上,Stringc被设计成ؓ不可改变(immutable)的类。如果你要改变其|可以Q但JVM在运行时Ҏ新值悄悄创Z一个新对象Q然后将q个对象的地址q回l原来类的引用。这个创E虽说是完全自动q行的,但它毕竟占用了更多的旉。在Ҏ间要求比较敏感的环境中,会带有一定的不良影响?/p>
再修改原来代码:
Stringstr1="abc";
Stringstr2="abc";str1="bcd";
Stringstr3=str1;
System.out.println(str3);//bcdStringstr4="bcd";
System.out.println(str1==str4);//true
我们再接着看以下的代码?/p>
Stringstr1=newString("abc");
Stringstr2="abc";
System.out.println(str1==str2);//false
创徏了两个引用。创Z两个对象。两个引用分别指向不同的两个对象?/p>
String str1 = "abc";
String str2 = new String("abc");
System.out.println(str1==str2); //false
创徏了两个引用。创Z两个对象。两个引用分别指向不同的两个对象?/p>
以上两段代码说明Q只要是用new()来新建对象的Q都会在堆中创徏Q而且其字W串是单独存值的Q即使与栈中的数据相同,也不会与栈中的数据共享?/p>
6. 数据cd包装cȝg可修攏V不仅仅是Stringcȝg可修改,所有的数据cd包装c都不能更改其内部的倹{?7. l论与徏议:
(1)我们在用诸如String str = "abc"Q的格式定义cLQL惛_然地认ؓQ我们创ZStringcȝ对象str。担心陷阱!对象可能q没有被创徏Q唯一可以肯定的是Q指向Stringcȝ引用被创Z。至于这个引用到底是否指向了一个新的对象,必须Ҏ上下文来考虑Q除非你通过new()Ҏ来显要地创徏一个新的对象。因此,更ؓ准确的说法是Q我们创Z一个指向Stringcȝ对象的引用变量strQ这个对象引用变量指向了某个gؓ"abc"的StringcR清醒地认识到这一点对排除E序中难以发现的bug是很有帮助的?/p>
(2)使用String str = "abc"Q的方式Q可以在一定程度上提高E序的运行速度Q因为JVM会自动根据栈中数据的实际情况来决定是否有必要创徏新对象。而对于String str = new String("abc")Q的代码Q则一概在堆中创徏新对象,而不其字符串值是否相{,是否有必要创建新对象Q从而加重了E序的负担。这个思想应该是n元模式的思想Q但JDK的内部在q里实现是否应用了这个模式,不得而知?/p>
(3)当比较包装类里面的数值是否相{时Q用equals()ҎQ当试两个包装cȝ引用是否指向同一个对象时Q用==?/p>
(4)׃Stringcȝimmutable性质Q当String变量需要经常变换其值时Q应该考虑使用StringBufferc,以提高程序效率?/p>
作?langm
版权声明Q本文可以自p{载,转蝲时请务必以超链接形式标明文章原始出处和作者信息及本声?
作?langm
原文:http://www.matrix.org.cn/resource/article/44/44056_NoClassDefDoundErr.html
关键?NoClassDefDoundErr ClassNotFoundException
在读q篇文章之前Q你最好了解一下Java的Exception机制?/p>
也许你在开发的q程中经常地见到ClassNotFoundException和NoClassDefFoundErrq两个异常,每每看到之后Q都会一概而论的是cL有找刎ͼ但有些时候见C们的时候又有些疑惑Q至我是这PQؓ什么Java要用两个异常来表C类定义没有扑ֈ那?他们之间有什么区别那Q?/p>
正y今天我又到了这个问题,Z的仔l研I了一下这两个异常的区别?
首先Q?
ClassNotFoundException直接l承与ExceptionQ它是一个checked的异常?
NoClassDefFoundErr l承自Error->LinkageError Q它是一个unchecked的异常?/p>
下面让我们看一下两个异常在API文档中的说明
ClassNotFoundExceptionQ?
当应用尝试用字符串名U通过下面的方法装载一个类时这个类的定义却没有扑ֈ时会抛出的异常?
Class.forName
ClassLoader.findSystemClass
ClassLoader.loadClass
NoClassDefFoundErrQ?
当JVM或者ClassLoader实例试装蝲一个类的定义(q通常是一个方法调用或者new表达式创Z个实例过E的一部分Q而这个类定义q没有找时所抛出的错误?
当编译的时候可以找到这个类的定义,但是以后q个cM再存在?/p>
q比较显而易见了吧,d文档是很重要的事情。这里我p一下我对这两个cȝ区别的理解?/p>
ClassNotFoundException异常只出现在你的应用E序d的装载类的过E中Q这个异常很多时候出现在我们的应用框架在初始化或者运行中动态装载已配置的类的过E中。这U情况下我们应该首先查我们的配置或者参数是否错误,是否企图装蝲一个ƈ不存在的c,如果配置没有错误Q我们就应该查看Classpath是否配置错误而导致ClassLoader无法扑ֈq个c,也应该检查要装蝲的类是否在一个jar包中而我们在引入q个jar包的q程中是否有遗漏或错误(q里jar包的版本也是一个需要格外注意的问题Q很多时候qjar包版本会造成太多的麻烦)?
NoClassDefFoundErr异常一般出现在我们~译环境和运行环境不一致的情况下,是说我们有可能在编译过后更改了Classpath或者jar包所以导致在q行的过E中JVM或者ClassLoader无法扑ֈq个cȝ定义Q我曄在编译后作了一ơjar包的清理Q然后应用就送给了我一个这LC物Q?/p>
我们l常用SDK开发应用,开发的q程中要引入很多jar包,有些SDK也会讑֮自己的Classpath。编译过E结束后在运行的q程中就要将已开发的应用和所有引入的jar包拷贝到应用服务器的相应目录下才可以q行Q而应用服务器使用的Classpath也很有可能与SDK的不同,在这个过E中有很大的几率造成双方环境不一致。所以很多开发者就会遇到在SDK中可以编译,q行也没有问题,但是同样的程序放到应用服务器上就出现NoClassDefFoundErrq个异常q种情况Q这是让初学者很挠头的一个问题?/p>
以上是我对q两个异常的一点个人理解,希望对各位开发者有所帮助Q可以让各位开发者在以后的开发过E中能够更快的找到问题所在。祝开发顺?/p>
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.SWT;
public class CopyOfGridLayoutExc {
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setText("Find (GridLayout)");
Label label = new Label(shell, SWT.NONE);
label.setText("Find what:");
Text text = new Text(shell, SWT.BORDER);
Button findButton = new Button(shell, SWT.PUSH);
findButton.setText("Find Next");
Group group = new Group(shell, SWT.NONE);
group.setLayout(new RowLayout());
Button upButton = new Button(group, SWT.RADIO);
upButton.setText("Up");
Button downButton = new Button(group, SWT.RADIO);
downButton.setText("Down");
downButton.setSelection(true);
group.setText("Direction");
Button cancelButton = new Button(shell, SWT.PUSH);
cancelButton.setText("Cancel");
/* Use a GridLayout to position the controls */
Monitor monitor = shell.getMonitor();
int width = monitor.getClientArea().width / 10;
GridLayout layout = new GridLayout(4, false);
layout.marginWidth = layout.marginHeight = 14;//layout leave's the window's space
shell.setLayout(layout);
GridData labelData =
new GridData(SWT.FILL, SWT.CENTER, false, false);
label.setLayoutData(labelData);
GridData textData =
new GridData(SWT.FILL,SWT.CENTER,true,false,2,1);
textData.widthHint = width;
text.setLayoutData(textData);
GridData findData =
new GridData(SWT.FILL, SWT.CENTER, false, false);
findButton.setLayoutData(findData);
GridData groupData =
new GridData(SWT.RIGHT,SWT.TOP,false,false,3,1);
group.setLayoutData(groupData);
GridData cancelData =
new GridData(SWT.FILL, SWT.TOP, false, false);
cancelButton.setLayoutData(cancelData);
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
display.dispose();
}
}
q其中我们在使用的时候应该要注意以下几点:
1.要选择自己适合 的Layoutcd.GridLayout适合于多U情?它大部分情况是用在较ؓ复杂的界面编E当?因ؓ复杂的界面会有相当多的控?
2.GridData的用将是一个控制界面显C的主要c?通过使用GridData我们可以很好的控制界?
其中GridData的构造函数比较多,但是相关的用我们都应该熟悉,特别是上面源E序当中使用的那个构造函?在用v来更Ҏ控制GridLayout的布局.通过horizantalSpan,VerticalSpan来控制控件所占用的单元格,q样׃控制其它控制是否在一列当中显C是在几列当中昄.前提是通过GridLayout.numColumns来设|列?
3.如果不设|GridData那么相关的控仉会按照相关的建立序加入到GridLayout当中.GridData不能控制控g的显C顺?而相关顺序是对象的徏立顺序来控制?q一点不要与GridDatah?
希望写这文章对大家学习SWT有用.
/**
* @author http://www.linewell.com <a href=mailto:cg@linewell.com>cg@linewell.com</a>
* @version 1.0
*/
public class Sort {
public void swap(int a[], int i, int j) {
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
public int partition(int a[], int low, int high) {
int pivot, p_pos, i;
p_pos = low;
pivot = a[p_pos];
for (i = low + 1; i <= high; i++) {
if (a[i] > pivot) {
p_pos++;
swap(a, p_pos, i);
}
}
swap(a, low, p_pos);
return p_pos;
}
public void quicksort(int a[], int low, int high) {
int pivot;
if (low < high) {
pivot = partition(a, low, high);
quicksort(a, low, pivot - 1);
quicksort(a, pivot + 1, high);
}
}
public static void main(String args[]) {
int vec[] = new int[] { 37, 47, 23, -5, 19, 56 };
int temp;
//选择排序?Selection Sort)
long begin = System.currentTimeMillis();
for (int k = 0; k < 1000000; k++) {
for (int i = 0; i < vec.length; i++) {
for (int j = i; j < vec.length; j++) {
if (vec[j] > vec[i]) {
temp = vec[i];
vec[i] = vec[j];
vec[j] = temp;
}
}
}
}
long end = System.currentTimeMillis();
System.out.println("选择法用时ؓQ? + (end - begin));
//打印排序好的l果
for (int i = 0; i < vec.length; i++) {
System.out.println(vec[i]);
}
// 冒排序?Bubble Sort)
begin = System.currentTimeMillis();
for (int k = 0; k < 1000000; k++) {
for (int i = 0; i < vec.length; i++) {
for (int j = i; j < vec.length - 1; j++) {
if (vec[j + 1] > vec[j]) {
temp = vec[j + 1];
vec[j + 1] = vec[j];
vec[j] = temp;
}
}
}
}
end = System.currentTimeMillis();
System.out.println("冒法用时ؓQ? + (end - begin));
//打印排序好的l果
for (int i = 0; i < vec.length; i++) {
System.out.println(vec[i]);
}
//插入排序?Insertion Sort)
begin = System.currentTimeMillis();
for (int k = 0; k < 1000000; k++) {
for (int i = 1; i < vec.length; i++) {
int j = i;
while (vec[j - 1] < vec[i]) {
vec[j] = vec[j - 1];
j--;
if (j <= 0) {
break;
}
}
vec[j] = vec[i];
}
}
end = System.currentTimeMillis();
System.out.println("插入法用时ؓQ? + (end - begin));
//打印排序好的l果
for (int i = 0; i < vec.length; i++) {
System.out.println(vec[i]);
}
//快速排序法(Quick Sort)
Sort s = new Sort();
begin = System.currentTimeMillis();
for (int k = 0; k < 1000000; k++) {
s.quicksort(vec, 0, 5);
}
end = System.currentTimeMillis();
System.out.println("快速法用时为:" + (end - begin));
//打印排序好的l果
for (int i = 0; i < vec.length; i++) {
System.out.println(vec[i]);
}
}
}
以下是运行结果:
选择法用时ؓQ?34
56
47
37
23
19
-5
冒法用时ؓQ?72
56
47
37
23
19
-5
插入法用时ؓQ?8
56
47
37
23
19
-5
快速法用时为:297
56
47
37
23
19
-5
Java学习|站
http://www-900.ibm.com/developerWorks/cn/java/index.shtml IBM的JAVA专题——永q的蓝色巨h
http://www.huihoo.com 灰狐动力——Enterprise Open Source
http://www.jdon.com J道——JAVA和J2EE解决之道
http://www.chinaunix.net ChinaUnix——我们在努力打造一个Unix时代Q?
http://www.theserverside.com TheServerSide.COM——Your Enterprise Java Community
http://www.onjava.com O'REILLY ON java.com
http://www.matrix.org.cn Matrix与Javap
http://www.java-source.net JavaSource
http://www.javaresearch.org Java研究l织——汇聚技术精?增进技术交?
http://www.cn-java.com 中文Java技术网——ؓJava爱好者服?
http://www.javalobby.org JavaLobby
http://www.javajia.com Java?
http://www.cnjavaclub.com 中国JAVA׃?
http://www.jspcn.net JSP中文|?
http://www.cnjsp.org 中国JSP技术网?
http://www.xuejava.com 学Java——学习Java的精?
http://tech.ccidnet.com 赛_|技术天?
http://www.uml.org.cn UML软g工程l织
http://dev2dev.bea.com.cn/index.jsp BEAdev2dev在线
http://www.kissjava.com 爪哇氓
http://java.about.com 来自About.com的Java新闻和技术文?
http://www.jcp.org/en/home/index Java Community Process
http://www.java-cn.com Java中文站——每一天我们都在进?
http://www.chedong.com/ 车东
http://www.javayou.com/ Java自由?
http://www.j2medev.com/ J2ME开发网
http://www.javadown.com.cn
http://www.java.net/
Java技术论坛?
http://bbs.chinajavaworld.com ChinaJavaWorld技术论?
http://www.javaworld.com.tw/jute/index.html JavaWorld技术论?
http://forum.javaeye.com Java视线论坛
http://www.jdon.com/jive/index.jsp J道论?
http://gceclub.sun.com.cn/NASApp/sme/jive/index.jsp Sun技术社?
http://www.cjsdn.com 中国Java开发网
http://spring.jactiongroup.net SpringFramework中文论坛
http://www.cartexpert.com/forum/forum.jsp?column=24 Jive研究论坛
http://www.javafan.net/jive/index.jsp JavaFan论坛
Java优秀Blog
javazhai.mblogger.cn
http://blog.donews.com/redtroy/
http://blog.csdn.net/casularm Casularm Blog
http://hedong.3322.org 竹笋炒肉
http://blog.csdn.net/baijsp Java and OpenSource Software
http://leosky.java.mblogger.cn leo的Blog
http://java2guru.java.mblogger.cn J2EE Blog
http://blog.csdn.net/chenyun2000 Open Java Project
http://gigix.blogdriver.com/gigix/index.html 透明思?
http://blog.tomxp.com/Home.html 东L的Blog
http://blog.csdn.net/liaoxingya276 liaoxingya的Blog
http://blog.csdn.net/arielxp !Java
http://www.nncn.com/blog/weblog.php HuiFei's Blog
http://www.donews.net/yahoo163/ BlogJava
Java热门QQ?
6927954 Java爱好者 ?5747018 Java开源框架研I?
2184090 Java最后通道 5464040 Java技术交?
6090680 Java讨论l ?6868040 Java讨论?
2848217 Java技术交 ?5287881 JavaC֛
3057466 Java世界 3657130 Java夜未?
4874250 Java开发者 ?6522650 Java联盟
4972763 Java爱好者 ?6880123 Java技术交?
2473372 Java学习班 ?6347116 Java学院
3049837 Java人生路 ?1407900 Java爱好?
2371661 Java最爱 ?7096701 Java思想与技?
4421567 Java菜鸟交流室 ?3493424 Java学习?
1822386 Java学习组 3905714 Java乐园
4085683 Java疯狂~程 5718771 JavaC
4578000 Jsp技术群 4384534 Jsp学习l?
4617990 Jsp学习班 ?1845656 Jsp爱好?
2493314 Jsp交流中心 3241217 Jsp专题学习
6788666 Jsp爱好者 ?3417234 Jsp交流
7378475 开发联盟Jsp学习 2347397 Java和Jsp技术讨?
1020937 Jsp 1693379 Jsp
200016 J2ME 4453572 J2ME
6074752 J2ME 4835602 J2ME
1772284 J2ME 155348 开发联?WAP J2ME
源代码下?
Zj2eeq_的大型电子商务网站源代码下蝲 :
本源代码可以帮助大家了解大型物品买卖和交换网站如淘宝Q易宝乐{网站的开发和创徏?br />下蝲地址: http://www.ebaole.com/sourcedown.html
q且开辟了一个社Z门ؓ大家提供源代码的交流和讨?
The Web offers many resources to help you use the Java platform. This section lists some that we use ourselves, or that we've heard good things about.
Caveat: A Web site that's good one year might stagnate the next, and it can be difficult to tell unless you know the site well. Please tell us if any of these Web sites is obsolete, or if you have a URL for an excellent resource not mentioned here.
We list three kinds of resources:
The Java Developer ConnectionSM
http://developer.java.sun.comCode ConventionsEssential. Here are some of the things you can do at the JDC:
- research bugs
- vote for which bugs should be fixed first
- view tutorials and book samples
- download early access software
- chat with developers and API architects
http://java.sun.com/docs/codeconv/Conventions that developers within Sun try to follow when writing programs in the Java programming language.About.com Focus on Java
http://java.about.comHas articles and links to many resources.JavaWorld Magazine
http://www.javaworld.netHas articles about current programming topics.Java Boutique
http://javaboutique.internet.comHas applets (some including source code), tutorials, book reviews, and more.Java Developer's Journal
http://www.sys-con.com/java/An online subset of a print magazine. Includes source code and selected articles.
The J2EETM Tutorial
http://java.sun.com/j2ee/tutorial/index.htmlA beginner's guide to developing enterprise applications on the Java 2 Platform, Enterprise Edition SDK.Java 3DTM API Tutorial
http://java.sun.com/products/java-media/3D/collateral/Has descriptions and examples of the most commonly used features in the Java 3D API.XML Technologies
http://java.sun.com/xml/tutorial_intro.htmlIntroduces XML and tells you how to use the Java XML APIs.The JNDI Tutorial
http://java.sun.com/products/jndi/tutorial/Tells you how to use the JavaTM Naming and Directory Interface (JNDI) for associating names and attributes with objects.JDC Tutorials
http://developer.java.sun.com/developer/onlineTraining/Many tutorials, covering a wealth of topics. Subjects include JavaBeans, Enterprise JavaBeans, JDBC, and Java 2D.The Swing Connection
http://java.sun.com/products/jfc/tsc/The Swing engineering team's Web site. Has articles written both by Swing creators and by external programmers who use Swing.The Swing/JFC FAQ
http://www.drye.com/java/faq.htmlUnofficial answers to frequently asked questions about Swing.Apple's Developer Site
http://developer.apple.com/java/For programmers who use Macs.
How To Write Unmaintainable Code
http://mindprod.com/unmain.htmlLong, funny essay on how (not) to write code that no one else can read.Slashdot
http://slashdot.org/search.pl?topic=108News and discussions about the Java platform.
[ Program To An Interface, Not An Implementation ]
n 接口是一个对象在对其它的对象q行调用时所知道的方法集合?/span>
n 一个对象可以有多个接口Q实际上Q接口是对象所有方法的一个子集)
n cd是对象的一个特定的接口?/span>
n 不同的对象可以具有相同的cdQ而且一个对象可以具有多个不同的cd?/span>
n 一个对象仅能通过其接口才会被其它对象所了解?/span>
n 某种意义上,接口是以一U非常局限的方式Q将“是一U?/span>?/span>”表达ؓ“一U支持该接口?/span>?/span>”?/span>
n 接口是实现插件化Q?/span>pluggabilityQ的关键
n 实现l承Q?i>cȝ?/i>Q:一个对象的实现是根据另一个对象的实现来定义的?/span>
n 接口l承Q?i>子类型化Q:描述了一个对象可在什么时候被用来替代另一个对象?/span>
n C++的承机制既指类l承Q又指接口ѝ?/span>
n C++通过l承U虚cL实现接口l承?/span>
n JavaҎ口承具有单独的语言构造方式-Java接口?/span>
n Java接口构造方式更加易于表辑֒实现那些专注于对象接口的设计?/span>
n 优点Q?/span>
F Client不必知道其用对象的具体所属类?/span>
F 一个对象可以很Ҏ地被Q实C相同接口的)的另一个对象所替换?/span>
F 对象间的q接不必绑定(hardwireQ到一个具体类的对象上Q因此增加了灉|性?/span>
F 松散藕合Q?/span>loosens couplingQ?/span>
F 增加了重用的可能性?/span>
F 提高了(对象Q组合的机率Q因包含对象可以是Q何实C一个指定接口的cR?/span>
n ~点Q?/span>
F 设计的复杂性略有增?/span>
Q译者注Q接口表C?/span>?/span>?/span>?/span>”(LikeAQ的关系Q承表C?/span>?/span>?/span>?/span>”(IsAQ的关系Q组合表C?/span>?/span>?/span>?/span>”(HasAQ的关系。)
该方法是指其它的一些类可以q行交通工LNQ而不必关心其实际上是Q汽车,轮船Q潜艇或是其它Q何实CIManeuverabre的对象)?/span>
内部cȝ使用的优~点Q?/p>
优点Q减了在类文g~译后的产生的字节码文g的大?br /> ~点QɽE序l构不清?/p>
使用内部cȝ注意事项Q?/p>
内部cȝ使用一般都与所在的外部cL一定的兌Q它是在一个类的内部嵌套定义的c,它可以是其它cȝ成员Q也可以在一个语句块的内部定义,q可以在表达式内部匿名定?匿名内部c??/p>
内部cL如下的特性:
.一般用在定义它的类或语句块之内Q在外部引用它时必须l出完整的名Uͼ名字不能与包含它的数癑相同
. 可以使用包含它的cȝ表态和实例成员变量Q也可以使用它所在方法的局部变?/p>
.可以定义为abstract
.若被声明为static,变成了层c,不能再用局部变?/p>
.若想在inner class 中声明Q何static成员Q则该inner class必须声明为static.
.匿名cL一U特D的内部c,它是在一个表辑ּ的内部包含一个完整的cȝ定义。匿名内部类不需要Q何的修饰词?/p>
.内部cd以用Q何听修饰W,但是如果声明为staticc,则等同于一个标准类?/p>
.如果非表态内部类Q就拥有对外部类的所有成员的完全讉K权限Q包括实例字D和Ҏ。ؓ实现q一行ؓQ非表态内部类存着对外部类的实例的一个隐匿的引用?/p>
.所以对一个非表态内部类q行实例化需要采用不同语法的new 语句Q这U开工的new 语句要求外部cȝ一个实例,使内部类能在那个实例的上下文中创建?/p>
.非表态内部类h一些限制。尤其是Q它们不能声明表态初始化列表和表态成员,除非是在帔R字段中。此外方法内部声明的内部cM能访问方法的局部变量和参数Q除非它们被初始化成final.
.表态内部类当中可以有表态数据,表态方法或者是又一个表态内部类。而非表态内部类当中不能有静态数据。这是它们的区别?/p>
.局部内部类QJava内部cM可以是局部的Q它可以定义在一个方法甚至一个代码块之内?/p>
有一炚w要注意的是,匿名内部cȝ于没有名字,所以它没有构造函敎ͼ但是如果q个匿名内部cȝ承了一个只含有带参数构造函数的父类Q创建它的时候必d上这些参敎ͼq在实现的过E中使用super关键字调用相应的内容Q。如果你惌初始化它的成员变量,有下面几U方法:
如果是在一个方法的匿名内部c,可以利用q个Ҏ传进你想要的参数Q不q记住,q些参数必须被声明ؓfinal?
匿名内部类攚w成有名字的局部内部类Q这样它可以拥有构造函C?
在这个匿名内部类中用初始化代码块?
Z么需要内部类Q?
java内部cL什么好处?Z么需要内部类Q?/p>
首先举一个简单的例子Q如果你惛_C个接口,但是q个接口中的一个方法和你构想的q个cM的一个方法的名称Q参数相同,你应该怎么办?q时候,你可以徏一个内部类实现q个接口。由于内部类对外部类的所有内定w是可讉K的,所以这样做可以完成所有你直接实现q个接口的功能?/p>
不过你可能要质疑Q更改一下方法的不就行了吗?
的确Q以此作计内部类的理由,实在没有说服力?/p>
真正的原因是q样的,java中的内部cd接口加在一P可以的解军_被C++E序员抱怨java中存在的一个问题——没有多l承。实际上QC++的多l承设计h很复杂,而java通过内部cd上接口,可以很好的实现多l承的效果?br />
下面是用内部类的几个小例子Q?br />
JAVA的内部类的构造方法是不会自动调用Q必d外部cd中的某个Ҏ当中或构造函数当中显C用才能够正确使用?/p>
Class Outer{
public outer(){
System.out.println("....");
}
Class Inner{
public Innter(){
System.out.println("inner");
}
}
public static void Main(String[] args){
Outer a = new Outer();
}
}
q种使用Ҏ不会关系到内部类的输出。因为它q没有显C用内部类?br />所以我们应该进行这L修改Q?/p>
在Outer构造函C加入 Innter b = new Innter();
可以直接调用它的输出或Ҏ体了?/p>
不过我们l常使用的还是匿名内部类Q?/p>
class Outer{
Outer(){
(new Inner(){
public void print(){
System.out.println("Inner");
}
}
).print();
System.out.println("Outer");
}
}
下面是JAVA的一个源码用了匿名内部c:
/**
* "Tokenizes" the entire stream as a single token.
*/
public class KeywordAnalyzer extends Analyzer {
public TokenStream tokenStream(String fieldName,
final Reader reader) {
return new TokenStream() {
private boolean done;
private final char[] buffer = new char[1024];
public Token next() throws IOException {
if (!done) {
done = true;
StringBuffer buffer = new StringBuffer();
int length = 0;
while (true) {
length = reader.read(this.buffer);
if (length == -1) break;
buffer.append(this.buffer, 0, length);
}
String text = buffer.toString();
return new Token(text, 0, text.length());
}
return null;
}
};
}
}
刚学Java语言Ӟ很隄解ؓ什么要有接口这个概念,虽说是可以实现所谓的多承,可一个只有方法名Q没有方法体的东西,我实现它又有什么用呢?我从它那什么也得不刎ͼ除了一些方法名Q我直接在具体类里加入这些方法不p了吗Q?/p>
Z么一定要有抽象类q个概念Qؓ什么就不能把这个父cd成一个具体的c,子类再承它不就可以了吗Q何必弄一个抽象类出来Q还要弄一些没有方法体的抽象方法,弄得又象接口又象cȝQ让人捉怸定?/p>
当我开始学习java设计模式Q真正走q面向对象设计的大门之后Q我才发玎ͼ自己寚w向对象设计的理解原来是那么的片面Q那么的肤浅Q根本就没有真正理解面向对象思想的精髓,在某一U程度上q受着面向q程的媄响,以ؓ弄出了一个个c,q是面向对象了Q而其实还是被q程所׃着?/p>
我还是说说我现在寚w向对象思想的理解吧Q不一定正全面,但我惛_该还是比以前略有进步吧?/p>
面向对象思想Q我觉得最关键的就是抽象?/strong>
一个Y件设计的好坏Q我惛_大程度上取决于它的整体架构,而这个整体架构其实就是你Ҏ个宏观商业业务的抽象框架Q当代表业务逻辑的高层抽象层l构合理Ӟ你底层的具体实现需要考虑的就仅仅是一些算法和一些具体的业务实现了。当你需要再开发另一个相q的目Ӟ你以前的抽象层说不定q可以再ơ利用呢Q面对对象的设计Q复用的重点其实应该是抽象层的复用,而不是具体某一个代码块的复用,是不是一下子感觉自己对复用理解的高度又上升了一层?^_^
说到了抽象,我就不能不提到曾让我头痛的Java接口和Java抽象cMQ这也是本文我想说的重点?/p>
既然面向对象设计的重点在于抽象,那Java接口和Java抽象cd有它存在的必然性了?/p>
Java接口和Java抽象cM表的是抽象cdQ就是我们需要提出的抽象层的具体表现。OOP面向对象的编E,如果要提高程序的复用率,增加E序的可l护性,可扩展性,必L面向接口的编E,面向抽象的编E,正确C用接口、抽象类q些太有用的抽象cd做ؓ你结构层ơ上的顶层?/p>
Java接口和Java抽象cL太多怼的地方,又有太多特别的地方,I竟在什么地方,才是它们的最佳位|呢Q把它们比较一下,你就可以发现了?/p>
1、Java接口和Java抽象cL大的一个区别,在于Java抽象cd以提供某些方法的部分实现Q而Java接口不可以,q大概就是Java抽象cd一的优点吧Q但q个优点非常有用?br />如果向一个抽象类里加入一个新的具体方法时Q那么它所有的子类都一下子都得Cq个新方法,而Java接口做不到这一点,如果向一个Java接口里加入一个新ҎQ所有实现这个接口的cd无法成功通过~译了,因ؓ你必让每一个类都再实现q个Ҏ才行Q这昄是Java接口的缺炏V?/p>
2、一个抽象类的实现只能由q个抽象cȝ子类l出Q也是_q个实现处在抽象cL定义出的l承的等U结构中Q而由于Java语言的单l承性,所以抽象类作ؓcd定义工具的效能大打折扣?br />在这一点上QJava接口的优势就出来了,M一个实C一个Java接口所规定的方法的c都可以hq个接口的类型,而一个类可以实现L多个Java接口Q从而这个类有了多U类型?/p>
3、从W?点不隄出,Java接口是定义合类型的理想工具Q合类表明一个类不仅仅具有某个主cd的行为,而且h其他的次要行为?/p>
4、结??点中抽象cdJava接口的各自优势,L典的设计模式出来了Q声明类型的工作仍然由Java接口承担Q但是同时给Z个Java抽象c,且实Cq个接口Q而其他同属于q个抽象cd的具体类可以选择实现q个Java接口Q也可以选择l承q个抽象c,也就是说在层ơ结构中QJava接口在最上面Q然后紧跟着抽象c,哈,q下两个的最大优炚w能发挥到极至了。这个模式就是“缺省适配模式”?br />在Java语言API中用了这U模式,而且全都遵@一定的命名规范QAbstract Q接口名?/p>
Java接口和Java抽象cȝ存在是Z用于具体cȝ实现和承的Q如果你准备写一个具体类ȝ承另一个具体类的话Q那你的设计有很大问题了。Java抽象cd是ؓ了承而存在的Q它的抽象方法就是ؓ了强制子cdd实现的?/p>
使用Java接口和抽象Javac进行变量的cd声明、参数是cd声明、方法的q还cd说明Q以及数据类型的转换{。而不要用具体Javac进行变量的cd声明、参数是cd声明、方法的q还cd说明Q以及数据类型的转换{?/font>
我想Q如果你~的代码里面q一个接口和抽象c都没有的话Q也许我可以说你Ҏ没有用到M设计模式QQ何一个设计模式都是和抽象分不开的,而抽象与Java接口和抽象Javac?/font>又是分不开的?/p>
理解抽象Q理解Java接口和抽象Javac,我想应该是真正开始用面向对象的思想d析问题,解决问题了吧
]]>
对与java中的final变量Qjava~译器是q行了优化的。每个用了finalcd变量的地斚w不会通过q接而进行访问。比如说TestcM使用了DatacM一个final的int数字fNumber=77Q这时候,java~译器会?7q个常数~译到Testcȝ指o码或者常量池中。这P每次Testcȝ到fNumber的时候,不会通过引用q接到DatacMq行dQ而是直接使用自己保存在类文g中的副本?
public class Test{
public static void main(String[] args){
System.out.println(Data.fNumber);
}
}
Data.java:
public class Data{
public static final int fNumber=77;
}
执行命o和结果:
Microsoft Windows XP [版本 5.1.2600]
(C) 版权所?1985-2001 Microsoft Corp.
C:\Documents and Settings\zangmeng>cd ..
C:\Documents and Settings>cd ..
C:\>javac Test.java
C:\>java Test
77
C:\>
q时候,我们更改Data.java的内容:
public class Data{
public static final int fNumber=777;
}
然后执行如下命oQ?/font>
C:\>javac Data.java
C:\>java Test
77
C:\>
q里我们看到Q虽然Data.java中的fNumber已经更改?77Q而且已经重新~译了,但是因ؓ~译器把fNumber的副本保存TestcMQ所以在重新~译Testcȝ前,TestcM直把fNumber认ؓ?7而不?77。下面我们变异Test.javaQ再执行Q看看结果?/font>
C:\>javac Test.java
C:\>java Test
777
C:\>
q时候,我们看到Q重新编译的Testcd新的777数值封装到了自q中?/font>
整个q程如下Q?br />Microsoft Windows XP [版本 5.1.2600]
(C) 版权所?1985-2001 Microsoft Corp.
C:\Documents and Settings\zangmeng>cd ..
C:\Documents and Settings>cd ..
C:\>javac Test.java
C:\>java Test
77
//在这里改变了Data.java的内?br />C:\>javac Data.java
C:\>java Test
77
C:\>javac Test.java
C:\>java Test
777
C:\>
String s0=”kvill? String s1=”kvill? String s2=”kv?+ “ill? System.out.println( s0==s1 ); System.out.println( s0==s2 ); |
true true |
String s0=”kvill? String s1=new String(”kvill?; String s2=”kv?+ new String(“ill?; System.out.println( s0==s1 ); System.out.println( s0==s2 ); System.out.println( s1==s2 ); |
false false false |
String s0= “kvill? String s1=new String(”kvill?; String s2=new String(“kvill?; System.out.println( s0==s1 ); System.out.println( ?*********?); s1.intern(); s2=s2.intern(); //把常量池中“kvill”的引用赋给s2 System.out.println( s0==s1); System.out.println( s0==s1.intern() ); System.out.println( s0==s2 ); |
false ********** false //虽然执行了s1.intern(),但它的返回值没有赋ls1 true //说明s1.intern()q回的是帔R池中”kvill”的引用 true |
String s1=new String("kvill"); String s2=s1.intern(); System.out.println( s1==s1.intern() ); System.out.println( s1+" "+s2 ); System.out.println( s2==s1.intern() ); |
false kvill kvill true |