http://tech.163.com u3usD{@Fd HX<1ALei zfU`JW&' 1.关于参数的传递
=2D+L\vE +CiaoR^i class ValHold{
+JU+l.H public int i = 10;
]]QFlN, [a }
xclu1uo5 public class ObParm{
Cra6.)* public void amethod(){
CHq$f{Okt& ValHold v = new ValHold();
;3 A6K[ another(v);
,jX6;Ai* System.out.println(v.i);
^'|r[Kl>m }
?m8&i$ public void another(ValHold v){
O\6;98 - v.i = 20;
FQ9*mT7@ ValHold vh = new ValHold();
/2YcTaZ v =vh;
=HCeIFh$ System.out.println(v.i);
i>GzzNY' }
-g1i_<5: public static void main(String[] argv){
*zqMuV? ObParm o = new ObParm();
C{$>ndk~ o.amethod();
_QB5)Jj h }
j2D}Gq }此题的答案是10,20,为什么不是10,10呢?
rPU*G,8J y S1Ql2y 这样解释吧,按照sun官方的说法:当一个引用变量作为参数传递给一个方法时, 在这个方法内可以改变变量的值,即改变引用指向的对象,(本题中将vh赋给v)但是方法的调用结束后,改变量恢复原来的值,即变量仍然指向原来的对象。 (即another(v)调用结束之后,v又回复到第一次ValHold v = new ValHold();时指向的地址空间。) 但是如果在方法内改变了引用指向的对象的数据(属性),那么当方法的调用结束后,尽管引用仍然指向原来的对象,这个对象的某个属性已经被改变了(v的i值在 执行v.i=20的时候就已经被改变了,所以调用another结束后,v.i已经变成了20) .
x|* y;dB W\N<?b|'^B 2.关于内部类
^xv<MQ^N "^53QIL0 public class InOut{
%G~ o%; String s= new String("Between");
d"f`D;I;i public void amethod(final int iArgs) {
/RX^i" i int iam;
ft > Ic class Bicycle{
< Pq]+;%{x Bicycle() {
r6Q :1^= System.out.println(s); //这两句话可以,也就是说可以访问s
^QuOd'{` System.out.println(iArgs); //和final int 常量
e )r-iVq //System.out.println(iOther);
LOpu J }
k(y MMT5 }
>b{Uv5S( new Bicycle();
Wwo- +^ }
K,[Ap_bn public void another(){
z8 wbO int iOther;
#oE-n^hR }
-@!8pUjU public static void main(String[] args) {
*oauil?\ InOut inout= new InOut();
E).w~<, inout.amethod(22);
LrOc V- }
]e[%Y"cC` }
4O;P0l:Fp Inner class能够存取外部类的所有实例变量----无论这些实例变量有什么样的存取控制符(比如private),就像类中的方法能够存取方法所在类的所有变量一样;如果inner class定义在方法中,则inner class能够存取方法所在的类中的实例变量,也能存取该方法中的局部变量,但该局部变量必须是final的,也就是只能访问方法中的常量.(上面所说的都是普通内部类,不是静态内部类的情况).
'?C?j`n=G Hr;(WOWR public class Testinner {
!Ip}:~Ri5 int t=10;
FTC+p8Be public void a() {
`iYC"G;` final int u =90;
t5*QF<b% class InMethod { //方法中内部类
hZ\M[g InMethod() { //内部类的构造方法
v<U 'b= System.out.println("u="+u); //封装方法内的变量必须是final才能访问到!
=|O!{awwE2 System.out.println("t="+t); //外部类的变量可以任意访问!
sPDeSP }
qK(P%n_ }
q8ijk.v8k new InMethod();//必须在方法a()中创建内部类对象之后,Testinner对象才能通过 a()访问到InMethod类
[\ib.~Ak }
LCl#_,c public static void main (String[] args) {
v!uB1v Testinner t= new Testinner();
q]+1yrj$ t.a();
LgR<9WW }
R1|qo^? }输出:u=90 ,t=10
D=/Dfs8Z 方法中的内部类不可以是static的!如果一个内部类是静态的(当然只能是类中的内部类啦),那么这个类就自动的成为顶级(top-level)类即普通的类。静态内部类中的方法(无论是静态的方法还是非静态的方法)只能直接访问外部类中的静态成员,要访问外部类中的非静态成员,则必须创建外部类的对象。
1.关于在静态方法中访问非静态内部类的问题 >.!GYx'X d
5"N},AN
public class Outer{ K;ONJUS 6S
public String name = "Outer"; hALH9W
public static void main(String argv[]){ ,]Cu2{!
//Inner myinner = new Inner(); //直接用这句话创建会编译错误 /]= erl
Outer myouter=new Outer(); //先创建外部类的对象 7(-o|f2
Outer.Inner myinner=myouter.new Inner(); lWxrr=
myinner.showName(); WLzA d$@
}//End of main +?{ +X hQ
//下面这段代码用来测试这种n烦的办法 ca)j^Y
public void amethod(){ a!f6<7&dg
Outer myouter=new Outer(); /@OT~G
Outer.Inner myinner=myouter.new Inner(); HJAz<
myinner.showName(); +ir;r{4
} {9$7C?bt[
//非静态方法访问非静态内部类 N -[Sh}
private class Inner{ ;<tQUn?
String name =new String("Inner"); g@C~?IvAS
void showName(){ @NLBDP=
System.out.println(name); r(Bi8Mx?
} odNkG:R.
}//End of Inner class V;qsPGmR
}在非静态方法访问非静态内部类直接创建该内部类的对象:new Inner().showName();当然也可以采取这种n烦的办法假设private class Inner改成static private class Inner, 那么在静态方法中访问静态内部类也是直接创建该内部类的对象,即Inner myinner = new Inner(),或者Outer.Inner myinner = new Outer.Inner()也行得通,可见这种n烦的方法在上面三种情况下都是可以用的。 }"y/KZ(
2.Abstract方法不能用final,static修饰非abstract方法在abstract类中可以用final,static G 0Z U!\
EYnOzwE
抽象类中的抽象方法不能是final,但是非抽象方法前加final可以编译通过因为abstract和final相互排斥,前者专用于继承,后者禁止继承 %^W.i"H0f
3 u(;;@_K
抽象类中的抽象方法不能为static D,R{vjP-
K;CiA9Q7
非抽象方法可以为static w,lz]Y,
Fcbf"T2J
包裹类Integer、 String 、Float、 Double等都是final类,不能被继承!Integer i=new Integer(“6”);如果字符串不是数字,会产生运行异常(不会出现编译错误)但是对于boolean,这个规则不适用。当字符串时(大小写无关),Boolean对象代表的数值为true,其他字符串均为false如: C+8/ l[
wQ~(e?-.?
Boolean b = new Boolean(“afiwou”); 代表false 9&oaq&
Boolean b = new Boolean(“tRue”); 是true3.多态性、虚拟方法调用 \;RBp5`2
or&.:B^\
public class Test8 { FI?S/G5
public static void main(String [] args){ o 9RJ
Base b = new Subclass(); :N:Z]Z>S2L
System.out.println(b.x); aR*jF)(
System.out.println(b.method()); ]tiP. u
} `,N2$;dTK
} BQdUDU y
class Base{ yES ]gam*
int x = 2; ;W9r$vK
int method(){ ^j\V})+
return x; |7BmQZhO:
} :BNM=0x_
} CLkTpK I`
class Subclass extends Base{ rOs29$m
int x = 3; [,j4Z>p=~
int method(){ Cf!hHP7
return x; <?# ?Vv
} NG3syv'
}结果是2,3,而不是3,3 *=rugbw
Employee e = new Manager(); eU2#*
e.department = " Finance " ; sL(U2A
//department 是Manager的一个特殊属性 |[I8sL=
声明变量e后,你能访问的对象部分只是Employee的部分;Manager的特殊部分是隐藏的。这是因为编译器应意识到,e 是一个Employee,而不是一个Manager。但重写的方法除外 [yBi{P},
NV>x#="
在你接收父类的一个引用时,你可以通过使用instanceof运算符判定该对象实际上是你所要的子类,并可以用类型转换该引用的办法来恢复对象的全部功能。为什么说“恢复对象的全部功能”,就是因为上一格所描述的,子类对象赋给父类句柄后,该句柄不能访问子类的那些特殊属性和方法,要用就要重新造型。这其实是多态参数的后续应用,形成这样一个链条:传入多态参数??instanceof判断类型??casting??恢复功能 o|)u B
. #M,Ga0H
Employee e = new Manager(); J R/aER
e.getDetails(); |Sh C2 .G
在此例中,Manager 重写了Employee的getDetail()方法。被执行的e.getDetails()方法来自对象的真实类型:Manager。事实上,执行了与变量的运行时类型(即,变量所引用的对象的类型)相关的行为,而不是与变量的编译时类型相关的行为。这是面向对象语言的一个重要特征。它也是多态性的一个特征,并通常被称作虚拟方法调用??“动态绑定”