讲述Java初学者必须要了解的两个常识
2008-01-05 18:17:43 来源:WEB开发网 闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閻愵剙鍔ょ紓宥咃躬瀵鎮㈤崗灏栨嫽闁诲酣娼ф竟濠偽i鍓х<闁诡垎鍐f寖闂佺娅曢幑鍥灳閺冨牆绀冩い蹇庣娴滈箖鏌ㄥ┑鍡欏嚬缂併劎绮妵鍕箳鐎n亞浠鹃梺闈涙搐鐎氫即鐛崶顒夋晬婵絾瀵ч幑鍥蓟閻斿摜鐟归柛顭戝枛椤牆顪冮妶搴′簼缂侇喗鎸搁悾鐑藉础閻愬秵妫冮崺鈧い鎺戝瀹撲礁鈹戦悩鎻掝伀缁惧彞绮欓弻娑氫沪閹规劕顥濋梺閫炲苯澧伴柟铏崌閿濈偛鈹戠€n€晠鏌嶆潪鎷屽厡闁汇倕鎳愮槐鎾存媴閸撴彃鍓卞銈嗗灦閻熲晛鐣烽妷褉鍋撻敐搴℃灍闁绘挻娲橀妵鍕箛闂堟稐绨肩紓浣藉煐濮樸劎妲愰幘璇茬闁冲搫鍊婚ˇ鏉库攽椤旂》宸ユい顓炲槻閻g兘骞掗幋鏃€鐎婚梺瑙勬儗閸樺€熲叺婵犵數濮烽弫鍛婃叏椤撱垹纾婚柟鍓х帛閳锋垶銇勯幒鍡椾壕缂備礁顦遍弫濠氱嵁閸℃稒鍊烽柛婵嗗椤旀劕鈹戦悜鍥╃У闁告挻鐟︽穱濠囨嚃閳哄啰锛滈梺褰掑亰閸欏骸鈻撳⿰鍫熺厸閻忕偟纭堕崑鎾诲箛娴e憡鍊梺纭呭亹鐞涖儵鍩€椤掑啫鐨洪柡浣圭墪閳规垿鎮欓弶鎴犱桓闂佸湱枪閹芥粎鍒掗弮鍫熷仺缂佸顕抽敃鍌涚厱闁哄洢鍔岄悘鐘绘煕閹般劌浜惧┑锛勫亼閸婃牠宕濋敃鈧…鍧楀焵椤掍胶绠剧€光偓婵犱線鍋楀┑顔硷龚濞咃絿妲愰幒鎳崇喓鎷犻懠鑸垫毐闂傚倷鑳舵灙婵炲鍏樺顐ゆ嫚瀹割喖娈ㄦ繝鐢靛У绾板秹寮查幓鎺濈唵閻犺櫣灏ㄥ銉р偓瑙勬尭濡繂顫忛搹鍦<婵☆垰鎼~宥囩磽娴i鍔嶉柟绋垮暱閻g兘骞嬮敃鈧粻濠氭偣閸パ冪骇鐎规挸绉撮—鍐Χ閸℃ê闉嶇紓浣割儐閸ㄥ墎绮嬪澶嬪€锋い鎺嶇瀵灝鈹戦埥鍡楃仯闁告鍕洸濡わ絽鍟崐鍨叏濡厧浜鹃悗姘炬嫹

核心提示:一、对象(object)与引用(reference)我们知道:A a = new A();产生一个A类型的对象,a是这个对象的的一个引用,讲述Java初学者必须要了解的两个常识,即a指向heap中真正的对象,而a和其他基本数据类型一起存放在stack中,因此,Java的参数,也就是object通过reference操控
一、对象(object)与引用(reference)
我们知道:
A a = new A();
产生一个A类型的对象,a是这个对象的的一个引用,即a指向heap中真正的对象,而a和其他基本数据类型一起存放在stack中。也就是object通过reference操控,在底层的话,a更象一个指针。
对于有些书本所说,a就是对象,初学者的话也没什么大问题,因为对a的操作,就是对a指向的对象的操作。
问题是,当a的指向发生改变时,a就是对象的说法就不能适应程序设计的需要。让我们来看一个简单的程序:
class A
{
PRivate int i=0;
public void setI(int x)
{
i=x;
}
public int getI()
{
return i;
}
}
public class MyRef1
{
public static void main(String[] args)
{
A a=new A();
A b=new A();
a.setI(10);
b.setI(15);
System.out.println("a的i="+a.getI());
System.out.println("b的i="+b.getI());
a=b;
a.setI(20);
System.out.println("a的i="+a.getI());
System.out.println("b的i="+b.getI());
}
}
我想,大家对于程序的输出应该认为是:
a的i=10
b的i=15
a的i=20
b的i=15
第一,第二行应该没什么异义,第三行是对a设置后i的值,问题是,第四行是不会输出i=15的,正确结果是:
i=20
因此,a,b都是对对象的引用,当我们将b的引用赋予a时,a已经重新指向了b,对指向发生改变后的a的操作,就是对b的操作。当然,那些坚持"a,b就是对象"说法的人,还是可以解释这个问题。
我们知道,java通过final来定义常量:
final int i=10;
当我们对一个常量重新赋值时,会发生编译错误:
i=5;//编译不通过
我们也可以通过final来定义常量对象:
final A a = new A();
这样的话,我们将不能对a重新赋值。
假如a本身是个对象,那么,这个对象就不能发生改变,其实,a只不过是一个引用,它只能指向原来指向的对象,
并不是说它所指的对象的状态不能改变,因此,我们可以通过不改变a原来的指向的情况下对对象状态进行改变,看程序:
class A
{
private int i=0;
public void setI(int x)
{
i=x;
}
public int getI()
{
return i;
}
}
public class MyRef1
{
public static void
main(String[] args)
{
final A a = new A();
System.out.println(a.getI());
a.setI(8);
System.out.println(a.getI());
}
}
假如a本身是个对象,那么,根本就不可能a.setI(8);而实际a是一个引用,程序可以编译并运行: 显示:8
总之,Java通过renfence来操控object,是深入学习Java知识的基础。
二,Java参数是值(value)传递还是引用(reference)传递我们先看程序:
public class MyRef2
{
static int x=10;
static int y=20;
public static void fangfa(int i)
{
i++;
x=i;
}
public static void main(String[] args)
{
System.out.println("x="+x);
System.out.println("y="+y);
MyRef2.fangfa(y);
System.out.println("x="+x);
System.out.println("y="+y);
}
}
显然,将显示:
x=10
y=20
x=21
y=20
y的值并没有发生改变,MyRef2.fangfa(y)使用的仅仅是y的值,里面的i++也不会作用到y本身。显然,java的参数是值传递,但是,为什么会有引用传递的说法呢?看下面这个程序:
class A
{
private int i=0;
public void setI(int x)
{
i=x;
}
public int getI()
return i;
}
}
public class MyRef1
{
public static void setA1(A newA,int t)
{
newA.setI(t);
}
public static void main(String[] args)
{
A a=new A();
System.out.println(a.getI());
MyRef1.setA1(a, 30);
System.out.println(a.getI());
}
}
按照值传递的说法,MyRef1.setA1(a,30);将使用a所指的对象的一个复件,最终对这个对象没有作用,而事实是,方法对这个对象起了作用,程序将显示0,30。那么,Java参数是值传递是不是错误了呢?其实并不是的,我们要记住,a只不过是对象的reference,而reference的复件与原来的reference指向的是同一个对象,我们对复件的操作,与对a的操作一样,最终还是对指向对象的操作,因此,Java的参数,只有值传递。
更多精彩
赞助商链接