add bookmarks...
import javax.servlet.*; import javax.servlet.http.*; import java.io.*; import java.util.*; import com.sun.image.codec.jpeg.*; import java.awt.*; import com.sun.image.codec.jpeg.*; import java.awt.image.BufferedImage; import java.awt.image.DataBuffer; import java.awt.geom.GeneralPath; import javax.swing.*; import java.math.*; public class Servlet1 extends HttpServlet { //Process the HTTP Get request public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType(CONTENT_TYPE); response.setContentType("image/jpeg"); //必须讄ContentType为image/jpeg int length = 4; //讄默认生成4个数?br /> Date d = new Date(); long lseed = d.getTime(); java.util.Random r = new Random(lseed); //讄随机U子 if (request.getParameter("length") != null) { try { length = Integer.parseInt(request.getParameter("length")); } catch (NumberFormatException e) { } } StringBuffer str = new StringBuffer(); for (int i = 0; i <length; i++) { str.append(r.nextInt(9)); //生成随机数字 } //可以在此加入保存验证码的代码 //创徏内存囑փ BufferedImage bi = new BufferedImage(40, 16, BufferedImage.TYPE_INT_RGB); Graphics2D g = bi.createGraphics(); g.clearRect(0, 0, 16, 40); g.setColor(Color.green.CYAN); g.drawString(str.toString(), 4, 12); try { //使用JPEG~码Q输出到response的输出流 JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(response. getOutputStream()); JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bi); param.setQuality(1.0f, false); encoder.setJPEGEncodeParam(param); encoder.encode(bi); } catch (Exception ex) { } } } |
然后在需求显C验证码的加入以下代码就可以?br />
<img alt="" src="/WebModule1/servlet1" width="40" height="16"/> |
?WebModule1/servlet1替换成你用来生成验证码的servlet的全路径?br />
Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q?/p>
以下是答案:(x)
Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q?/p>
W一Q谈谈final, finally, finalize的区别?br /> final—修饰符Q关键字Q如果一个类被声明ؓ(f)finalQ意味着它不能再z出新的子c,不能作ؓ(f)父类被ѝ因此一个类不能既被声明?abstract的,又被声明为final的。将变量或方法声明ؓ(f)finalQ可以保证它们在使用中不被改变。被声明为final的变量必d声明时给定初|而在以后的引用中只能dQ不可修攏V被声明为final的方法也同样只能使用Q不能重?br /> finally—再异常处理时提?finally 块来执行M清除操作。如果抛Z个异常,那么相匹配的 catch 子句׃(x)执行Q然后控制就?x)进?finally 块(如果有的话)?br /> finalize—方法名。Java 技术允怋?finalize() Ҏ(gu)在垃圾收集器对象从内存中清除出M前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对q个对象调用的。它是在 Object cM定义的,因此所有的c都l承了它。子c覆?finalize() Ҏ(gu)以整理系l资源或者执行其他清理工作。finalize() Ҏ(gu)是在垃圾攉器删除对象之前对q个对象调用的?br />
W二QAnonymous Inner Class (匿名内部c? 是否可以extends(l承)其它c,是否可以implements(实现)interface(接口)?
匿名的内部类是没有名字的内部cR不能extends(l承) 其它c,但一个内部类可以作ؓ(f)一个接口,由另一个内部类实现?br />
W三QStatic Nested Class ?Inner Class的不同,说得多好(面试题有的很W统)?br /> Nested Class Q一般是C++的说法)QInner Class (一般是JAVA的说?。Java内部cMC++嵌套cL大的不同在于是否有指向外部的引用上。具体可见http: //www.frontfree.net/articles/services/view.asp?id=704&page=1
注:(x) 静态内部类QInner ClassQ意味着1创徏一个static内部cȝ对象Q不需要一个外部类对象Q?不能从一个static内部cȝ一个对象访问一个外部类对象
Hashtablel承自Dictionaryc,而HashMap是Java1.2引进的Map interface的一个实?
HashMap允许null作ؓ(f)一个entry的key或者valueQ而Hashtable不允?
q有是QHashMap把Hashtable的containsҎ(gu)L了,Ҏ(gu)containsvalue和containsKey。因为containsҎ(gu)Ҏ(gu)让h引v误解?
最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是Q在
多个U程讉KHashtableӞ不需要自׃ؓ(f)它的Ҏ(gu)实现同步Q而HashMap
必Mؓ(f)之提供外同步?br /> W四Q?amp;?amp;&的区别?br /> &是位q算W?amp;&是布?yu)(dng)逻辑q算W?br />
W五QHashMap和Hashtable的区别?br /> 都属于Map接口的类Q实C惟一键映到特定的g?br /> HashMap cL有分cL者排序。它允许一?null 键和多个 null 倹{?
Hashtable cM?HashMapQ但是不允许 null 键和 null 倹{它也比 HashMap 慢,因ؓ(f)它是同步的?br /> Hashtablel承自Dictionaryc,而HashMap是Java1.2引进的Map interface的一个实?
q有是QHashMap把Hashtable的containsҎ(gu)L了,Ҏ(gu)containsvalue和containsKey。因为containsҎ(gu)Ҏ(gu)让h引v误解?
最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是Q在
多个U程讉KHashtableӞ不需要自׃ؓ(f)它的Ҏ(gu)实现同步Q而HashMap
必Mؓ(f)之提供外同步?
W六QCollection ?Collections的区别?br /> Collections是个java.util下的c,它包含有各种有关集合操作的静态方法?br /> Collection是个java.util下的接口Q它是各U集合结构的父接?
W七Q什么时候用assert?br /> 断言是一个包含布?yu)(dng)表辑ּ的语句,在执行这个语句时假定该表辑ּ?true。如果表辑ּ计算?falseQ那么系l会(x)报告一?AssertionError。它用于调试目的Q?
assert(a > 0); // throws an AssertionError if a <= 0
断言可以有两UŞ式:(x)
assert Expression1 ;
assert Expression1 : Expression2 ;
Expression1 应该L产生一个布?yu)(dng)倹{?
Expression2 可以是得Z个值的L表达式。这个值用于生成显C更多调试信息的 String 消息?br /> 断言在默认情况下是禁用的。要在编译时启用断言Q需要?source 1.4 标记Q?
javac -source 1.4 Test.java
要在q行时启用断aQ可使用 -enableassertions 或?-ea 标记?
要在q行旉择用断言Q可使用 -da 或?-disableassertions 标记?
要系l类中启用断aQ可使用 -esa 或?-dsa 标记。还可以在包的基上启用或者禁用断a?
可以在预计正常情况下不会(x)到达的Q何位|上攄断言。断a可以用于验证传递给U有Ҏ(gu)的参数。不q,断言不应该用于验证传递给公有Ҏ(gu)的参敎ͼ因ؓ(f)不管是否启用了断aQ公有方法都必须查其参数。不q,既可以在公有Ҏ(gu)中,也可以在非公有方法中利用断言试后置条g。另外,断言不应该以M方式改变E序的状态?
W八QGC是什? Z么要有GC? (基础)?br /> GC是垃圾收集器。Java E序员不用担心内存管理,因ؓ(f)垃圾攉器会(x)自动q行理。要h垃圾攉Q可以调用下面的Ҏ(gu)之一Q?
System.gc()
Runtime.getRuntime().gc()
W九(ji)QString s = new String("xyz");创徏了几个String Object?
两个对象Q一个是“xyx?一个是指向“xyx”的引用对象s?br />
W十QMath.round(11.5){於多少? Math.round(-11.5){於多少?
Math.round(11.5)q回QlongQ?2QMath.round(-11.5)q回QlongQ?11;
W十一Qshort s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?
short s1 = 1; s1 = s1 + 1;有错Qs1是short型,s1+1是int?不能昑ּ转化为short型。可修改为s1 =(short)(s1 + 1) 。short s1 = 1; s1 += 1正确?br />
W十二,sleep() ?wait() 有什么区? 搞线E的最?br /> sleep()Ҏ(gu)是ɾU程停止一D|间的Ҏ(gu)。在sleep 旉间隔期满后,U程不一定立x复执行。这是因为在那个时刻Q其它线E可能正在运行而且没有被调度ؓ(f)攑ּ执行Q除?a)“醒来”的U程h更高的优先
(b)正在q行的线E因为其它原因而阻塞?br /> wait()是线E交互时Q如果线E对一个同步对象x 发出一个wait()调用Q该U程?x)暂停执行,被调对象q入{待状态,直到被唤醒或{待旉到?br /> W十三,Java有没有goto?
Goto—java中的保留字,现在没有在java中用?br />
W十四,数组有没有length()q个Ҏ(gu)? String有没有length()q个Ҏ(gu)Q?br /> 数组没有length()q个Ҏ(gu)Q有length的属性?br /> String有有length()q个Ҏ(gu)?br />
W十五,Overload和Override的区别。Overloaded的方法是否可以改变返回值的cd?
Ҏ(gu)的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父cM子类之间多态性的一U表玎ͼ重蝲Overloading是一个类中多态性的一U表现。如果在子类中定义某Ҏ(gu)与其父类有相同的名称和参敎ͼ我们说该Ҏ(gu)被重?(Overriding)。子cȝ对象使用q个Ҏ(gu)Ӟ调用子cM的定义,对它而言Q父cM的定义如同被“屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参C数或有不同的参数cdQ则UCؓ(f)Ҏ(gu)的重?Overloading)。Overloaded的方法是可以改变q回值的cd?br />
W十六,Set里的元素是不能重复的Q那么用什么方法来区分重复与否? 是用==q是equals()? 它们有何区别?
Set里的元素是不能重复的Q那么用iterator()Ҏ(gu)来区分重复与否。equals()是判M个Set是否相等?br /> equals()?=Ҏ(gu)军_引用值是否指向同一对象equals()在类中被覆盖Qؓ(f)的是当两个分ȝ对象的内容和cd盔R的话Q返回真倹{?br />
W十七,l我一个你最常见到的runtime exception?br /> ArithmeticException, ArrayStoreException, BufferOverflowException, BufferUnderflowException, CannotRedoException, CannotUndoException, ClassCastException, CMMException, ConcurrentModificationException, DOMException, EmptyStackException, IllegalArgumentException, IllegalMonitorStateException, IllegalPathStateException, IllegalStateException,
ImagingOpException, IndexOutOfBoundsException, MissingResourceException, NegativeArraySizeException, NoSuchElementException, NullPointerException, ProfileDataException, ProviderException, RasterFormatException, SecurityException, SystemException, UndeclaredThrowableException, UnmodifiableSetException, UnsupportedOperationException
W十八,error和exception有什么区?
error 表示恢复不是不可能但很困隄情况下的一U严重问题。比如说内存溢出。不可能指望E序能处理这L(fng)情况?br /> exception 表示一U设计或实现问题。也是_(d)它表C如果程序运行正常,从不?x)发生的情况?br /> W十?ji),List, Set, Map是否l承自Collection接口?
ListQSet?br />
Map不是
W二十,abstract class和interface有什么区?
声明Ҏ(gu)的存在而不d现它的类被叫做抽象类Qabstract classQ,它用于要创徏一个体现某些基本行为的c,qؓ(f)该类声明Ҏ(gu)Q但不能在该cM实现该类的情c(din)不能创建abstract cȝ实例。然而可以创Z个变量,其类型是一个抽象类Qƈ让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract cȝ子类为它们父cM的所有抽象方法提供实玎ͼ否则它们也是抽象cMؓ(f)。取而代之,在子cM实现该方法。知道其行ؓ(f)的其它类可以在类中实现这些方法?br /> 接口QinterfaceQ是抽象cȝ变体。在接口中,所有方法都是抽象的。多l承性可通过实现q样的接口而获得。接口中的所有方法都是抽象的Q没有一个有E序体。接口只可以定义static final成员变量。接口的实现与子cȝ|除了该实现类不能从接口定义中l承行ؓ(f)。当cd现特D接口时Q它定义Q即程序体l予Q所有这U接口的Ҏ(gu)。然后,它可以在实现了该接口的类的Q何对象上调用接口的方法。由于有抽象c,它允怋用接口名作ؓ(f)引用变量的类型。通常的动态联~将生效。引用可以{换到接口cd或从接口cd转换Qinstanceof q算W可以用来决定某对象的类是否实现了接口?br />
W二十一Qabstract的method是否可同时是static,是否可同时是nativeQ是否可同时是synchronized?
都不?br />
W二十二Q接口是否可l承接口? 抽象cL否可实现(implements)接口? 抽象cL否可l承实体c?concrete class)?
接口可以l承接口。抽象类可以实现(implements)接口Q抽象类是否可承实体类Q但前提是实体类必须有明的构造函数?br />
W二十三Q启动一个线E是用run()q是start()?
启动一个线E是调用start()Ҏ(gu)QɾU程所代表的虚拟处理机处于可运行状态,q意味着它可以由JVM调度q执行。这q不意味着U程׃(x)立即q行。run()Ҏ(gu)可以产生必须退出的标志来停止一个线E?br /> W二十四Q构造器Constructor是否可被override?
构造器Constructor不能被承,因此不能重写OverridingQ但可以被重载Overloading?br />
W二十五Q是否可以承Stringc?
StringcLfinalcL不可以ѝ?br />
W二十六Q当一个线E进入一个对象的一个synchronizedҎ(gu)后,其它U程是否可进入此对象的其它方?
不能Q一个对象的一个synchronizedҎ(gu)只能׃个线E访问?br />
W二十七Qtry {}里有一个return语句Q那么紧跟在q个try后的finally {}里的code?x)不会(x)被执行Q什么时候被执行Q在return前还是后?
?x)执行,在return前执行?br />
W二十八Q编E题: 用最有效率的Ҏ(gu)出2乘以8{於?
有C背景的程序员特别喜欢问这U问题?br />
2 << 3
W二十九(ji)Q两个对象值相?x.equals(y) == true)Q但却可有不同的hash codeQ这句话对不?
不对Q有相同的hash code?br />
W三十,当一个对象被当作参数传递到一个方法后Q此Ҏ(gu)可改变这个对象的属性,q可q回变化后的l果Q那么这里到底是g递还是引用传?
是g递。Java ~程语言只由g递参数。当一个对象实例作Z个参数被传递到Ҏ(gu)中时Q参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变Q但对象的引用是永远不会(x)改变的?br />
W三十一Qswtich是否能作用在byte上,是否能作用在long上,是否能作用在String?
switchQexpr1Q中Qexpr1是一个整数表辑ּ。因此传递给 switch ?case 语句的参数应该是 int?short?char 或?byte。long,string 都不能作用于swtich?br /> W三十二Q编E题: 写一个Singleton出来?br /> Singleton模式主要作用是保证在Java应用E序中,一个类Class只有一个实例存在?br /> 一般Singleton模式通常有几U种形式:
W一UŞ? 定义一个类Q它的构造函Cؓ(f)private的,它有一个static的private的该cd量,在类初始化时实例话,通过一个public的getInstanceҎ(gu)获取对它的引?l而调用其中的Ҏ(gu)?br /> public class Singleton {
private Singleton(){}
//在自己内部定义自׃个实例,是不是很奇怪?
//注意q是private 只供内部调用
private static Singleton instance = new Singleton();
//q里提供了一个供外部讉K本class的静态方法,可以直接讉K
public static Singleton getInstance() {
return instance;
}
}
W二UŞ?
public class Singleton {
private static Singleton instance = null;
public static synchronized Singleton getInstance() {
//q个Ҏ(gu)比上面有所改进Q不用每ơ都q行生成对象Q只是第一?
//使用时生成实例,提高了效率!
if (instance==null)
instanceQnew Singleton();
return instance; }
}
其他形式:
定义一个类Q它的构造函Cؓ(f)private的,所有方法ؓ(f)static的?br /> 一般认为第一UŞ式要更加安全
Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=
以下是PCOnline的网友评论:(x)http://cmt.pconline.com.cn/topic.jsp?id=115964&reverse=1
|
|
|
|
|
|
3.q行zcȝmainҎ(gu)?/p>
4.初始化基cM的其他成员变量(staticcd的除外)?/p>
5.调用基类构造函数?/p>
6.初始化派生类中的其他成员变量Qstaticcd的除外)?/p>
7.调用zcL造函数?/p>
for example:
Beetle.java
class Insect {
private int i = 9;
private int l = print("Insect.l initialized");
protected int j ;
public Insect(){
System.out.println("i="+i+" j="+j);
j = 39;
}
private static int x1 = print("static Insect.x1 initialized");
static int print(String s){
System.out.println(s);
return 47;
}
}
public class Beetle extends Insect{
private int k = print("Beetle.k initialized");
//private int j=100;
public Beetle(){
System.out.println("k = "+k);
System.out.println("j = "+j);
}
private static int y = print("Beetle.y initialized");
public static void main(String[] args) {
System.out.println("Beetle constructor");
Beetle b = new Beetle();
//Insect i = new Insect();
}
}
q行输出Q?/p>
static Insect.x1 initialized
Beetle.y initialized
Beetle constructor
Insect.l initialized
i=9 j=0
Beetle.k initialized
k = 47
j = 39
1. 单类型是按g递的
Java Ҏ(gu)的参数是单类型的时候,是按g递的 (pass by value)。这一Ҏ(gu)们可以通过一个简单的例子来说明:(x)
/* ?1 */
/**
* @(#) Test.java
* @author fancy
*/
public class Test { public static void test(boolean test) { test = ! test; System.out.println("In test(boolean) : test = " + test); } public static void main(String[] args) { boolean test = true; System.out.println("Before test(boolean) : test = " + test); test(test); System.out.println("After test(boolean) : test = " + test); } }
q行l果Q?/p>
Before test(boolean) : test = true
In test(boolean) : test = false
After test(boolean) : test = true
不难看出Q虽然在 test(boolean) Ҏ(gu)中改变了传进来的参数的|但对q个参数源变量本wƈ没有影响Q即?main(String[]) Ҏ(gu)里的 test 变量没有影响。那说明Q参数类型是单类型的时候,是按g递的。以参数形式传递简单类型的变量Ӟ实际上是参数的g了一个拷贝传q方法函数的Q那么在Ҏ(gu)函数里再怎么改变其|其结果都是只改变了拷贝的|而不是源倹{?/p>
2. 什么是引用
Java 是传D是传引用Q问题主要出在对象的传递上Q因?Java 中简单类型没有引用。既然争Z提到了引用这个东西,Z搞清楚这个问题,我们必须要知道引用是什么?/p>
单的_(d)引用其实像是一个对象的名字或者别?(alias)Q一个对象在内存中会(x)h一块空间来保存数据Q根据对象的大小Q它可能需要占用的I间大小也不{。访问对象的时候,我们不会(x)直接是访问对象在内存中的数据Q而是通过引用去访问。引用也是一U数据类型,我们可以把它惌为类?C 语言中指针的东西Q它指示了对象在内存中的地址——只不过我们不能够观察到q个地址I竟是什么?/p>
如果我们定义了不止一个引用指向同一个对象,那么q些引用是不相同的,因ؓ(f)引用也是一U数据类型,需要一定的内存I间来保存。但是它们的值是相同的,都指C同一个对象在内存的中位置。比?/p>
String a = "Hello";
String b = a;
q里Qa ?b 是不同的两个引用Q我们用了两个定义语句来定义它们。但它们的值是一L(fng)Q都指向同一个对?"Hello"。也怽q觉得不够直观,因ؓ(f) String 对象的值本w是不可更改?(?b = "World"; b = a; q种情况不是改变?"World" q一对象的|而是改变了它的引?b 的g之指向了另一?String 对象 a)。那么我们用 StringBuffer 来D一个例子:(x)
/* ?2 */
/**
* @(#) Test.java
* @author fancy
*/
public class Test { public static void main(String[] args) { StringBuffer a = new StringBuffer("Hello"); StringBuffer b = a; b.append(", World"); System.out.println("a is " + a); } }
q行l果Q?/p>
a is Hello, World
q个例子?a ?b 都是引用Q当改变?b 指示的对象的值的时候,从输出结果来看,a 所指示的对象的g改变了。所以,a ?b 都指向同一个对象即包含 "Hello" 的一?StringBuffer 对象?/p> q里我描qC两个要点Q?
3. 对象是如何传递的?/strong>
关于对象的传递,有两U说法,即“它是按g递的”和“它是按引用传递的”。这两种说法各有各的道理Q但是它们都没有从本质上d析,卌于生了争论?/p>
既然现在我们已经知道了引用是什么东西,那么现在不妨来分析一下对象作是参数是如何传递的。还是先以一个程序ؓ(f)例:(x)
/* ?3 */
/**
* @(#) Test.java
* @author fancy
*/
public class Test { public static void test(StringBuffer str) { str.append(", World!"); } public static void main(String[] args) { StringBuffer string = new StringBuffer("Hello"); test(string); System.out.println(string); } }
q行l果Q?/p> Hello, World!
test(string) 调用?test(StringBuffer) Ҏ(gu)Qƈ?string 作ؓ(f)参数传递了q去。这?string 是一个引用,q一Ҏ(gu)勿庸|疑的。前面提刎ͼ引用是一U数据类型,而且不是对象Q所以它不可能按引用传递,所以它是按g递的Q它么它的值究竟是什么呢Q是对象的地址?/p>
由此可见Q对象作为参数的时候是按g递的Q对吗?错!Z么错Q让我们看另一个例子:(x)
/* ?4 */
/**
* @(#) Test.java
* @author fancy
*/
public class Test { public static void test(String str) { str = "World"; } public static void main(String[] args) { String string = "Hello"; test(string); System.out.println(string); } }
q行l果Q?/p>
Hello
Z么会(x)q样呢?因ؓ(f)参数 str 是一个引用,而且它与 string 是不同的引用Q虽然它们都是同一个对象的引用。str = "World" 则改变了 str 的|使之指向了另一个对象,然?str 指向的对象改变了Q但它ƈ没有?"Hello" 造成M影响Q而且׃ string ?str 是不同的引用Qstr 的改变也没有?string 造成M影响Q结果就如例中所C?/p>
其结果是推翻了参数按g递的说法。那么,对象作ؓ(f)参数的时候是按引用传递的了?也错Q因Z一个例子的能够说明它是按g递的?/p>
l果Q就像光到底是Lq是_子的问题一PJava Ҏ(gu)的参数是按什么传递的问题Q其{案只能是Q即是按g递也是按引用传递,只是参照物不同,l果也就不同?/p>
4. 正确看待传D是传引用的问?/strong>
要正的看待q个问题必须要搞清楚Z么会(x)有这样一个问题?/p>
实际上,问题来源?CQ而不?Java?/p>
C 语言中有一U数据类型叫做指针,于是一个数据作为参C递给某个函数的时候,有两种方式Q传|或是传指针,它们的区别,可以用一个简单的例子说明Q?/p>
/* ?5 */
/**
* @(#) test.c
* @author fancy
*/
void SwapValue(int a, int b) { int t = a; a = b; b = t; } void SwapPointer(int * a, int * b) { int t = * a; * a = * b; * b = t; } void main() { int a = 0, b = 1; printf("1 : a = %d, b = %d\n", a, b); SwapValue(a, b); printf("2 : a = %d, b = %d\n", a, b); SwapPointer(&a, &b); printf("3 : a = %d, b = %d\n", a, b); }
q行l果Q?/p>
1 : a = 0, b = 1
2 : a = 0, b = 1
3 : a = 1, b = 0
大家可以明显的看刎ͼ按指针传递参数可以方便的修改通过参数传递进来的|而按g递就不行?/p>
?Java 成长h的时候,许多?C E序员开始{向学?JavaQ他们发玎ͼ使用cM SwapValue 的方法仍然不能改变通过参数传递进来的单数据类型的|但是如果是一个对象,则可能将其成员随意更攏V于是他们觉得这很像?C 语言中传?传指针的问题。但?Java 中没有指针,那么q个问题演变成了传?传引用的问题。可惜将q个问题攑֜ Java 中进行讨论ƈ不恰当?/p>
讨论q样一个问题的最l目的只是ؓ(f)了搞清楚何种情况才能在方法函C方便的更改参数的值ƈ使之长期有效?/p>
Java 中,改变参数的值有两种情况Q第一U,使用赋值号?”直接进行赋g其改变,如例 1 和例 4Q第二种Q对于某些对象的引用Q通过一定途径对其成员数据q行改变Q如?3。对于第一U情况,其改变不?x)媄响到?gu)该方法以外的数据Q或者直接说源数据。而第二种Ҏ(gu)Q则相反Q会(x)影响到源数据——因为引用指C的对象没有变,对其成员数据q行改变则实质上是改变的该对象?/p>
5. 如何实现cM swap 的方?/strong>
传D是传引用的问题,到此已经是解决了,但是我们仍然不能解决q样一个问题:(x)如果我有两个 int 型的变量 a ?bQ我惛_一个方法来交换它们的|应该怎么办?
l论很让人失望——没有办法!因此Q我们只能具体情况具体讨论,以经怋用交换方法的排序ZQ?/p>
/** ?6 */
/**
* @(#) Test.java
* @author fancy
*/
public class Test { public static void swap(int[] data, int a, int b) { int t = data[a]; data[a] = data[b]; data[b] = t; } public static void main(String[] args) { int[] data = newint[10]; for (int i = 0; i < 10; i++) { data[i] = (int) (Math.random() * 100); System.out.print(" " + data[i]); } System.out.println(); for (int i = 0; i < 9; i++) { for (int j = i; j < 10; j++) { if (data[i] > data[j]) { swap(data, i, j); } } } for (int i = 0; i < 10; i++) { System.out.print(" " + data[i]); } System.out.println(); } }
q行l果(情况之一)Q?/p>
78 69 94 38 95 31 50 97 84 1
1 31 38 50 69 78 84 94 95 97
swap(int[] data, int a, int b) Ҏ(gu)在内部实际上是改变了 data 所指示的对象的成员数据Q即上述讨论的第二种改变参数值的Ҏ(gu)。希望大家能够D一反三Q用类似的Ҏ(gu)来解决相关问题?br />---------------------------------------------------------------------------------------
上面的文字是|上扄,我觉得对象传递还是属于引用传?对于上面的两D代?都可以按引用传递的方式说明:
/* ?3 */
/**
* @(#) Test.java
* @author fancy
*/
public class Test { public static void test(StringBuffer str) { str.append(", World!"); } public static void main(String[] args) { StringBuffer string = new StringBuffer("Hello"); test(string); System.out.println(string); } }
q行l果Q?/p>
Hello, World!
1.string 引用传递给test Ҏ(gu)---->2.str 和string 引用指向同一个对?Hello" ----->3.str引用改变了它和string引用指向的同一对象"Hello"----->4.所以System.out.println(string);后的对象也变?br />
对于:
/* ?4 */
/**
* @(#) Test.java
* @author fancy
*/
public class Test { public static void test(String str) { str = "World"; } public static void main(String[] args) { String string = "Hello"; test(string); System.out.println(string); } }
q行l果Q?/p>
Hello
1.string 引用传递给test Ҏ(gu)---->2.str 和string 引用指向同一个对?Hello" ----->3.str引象指向了别的对?World",而没有媄响string引用对象的对?Hello" ---->4.所以System.out.println(string);后的对象q是Hello
对于:
public class Test {
String name;
public void setName(String s) {
name = s;
}
public String getName(){
return name;
}
public void call(Test t) {
Test t2 = new Test();
t2.setName("cba");
t.setName("abc");
t = t2 ;
}
public static void main(String[] arg) {
Test obj = new Test();
obj.call (obj) ;
System.out.println("obj's name: "+obj.getName());
}
}
也可以类似的理解,l果?obj's name: abc