1.
abstractclassName{
privateStringname;
publicabstractbooleanisStupidName(Stringname){}
}
大侠们,这有何错误?
答案:错。abstractmethod必须以分号结尾,且不带花括号。
2.
publicclassSomething{
voiddoSomething(){
privateStrings="";
intl=s.length();
}
}
有错吗?
答案:错。局部变量前不能放置任何访问修饰符(private,public,和protected)。final可以用来修饰局部变量
(final如同abstract和strictfp,都是非访问修饰符,strictfp只能修饰class和method而非variable)。
3.
abstractclassSomething{
privateabstractStringdoSomething();
}
这好像没什么错吧?
答案:错。abstract的methods不能以private修饰。abstract的methods就是让子类implement(实现)具体细节的,怎么可以用private把abstract
method封锁起来呢?(同理,abstractmethod前不能加final)。
4.
publicclassSomething{
publicintaddOne(finalintx){
return++x;
}
}
这个比较明显。
答案:错。intx被修饰成final,意味着x不能在addOnemethod中被修改。
5.
publicclassSomething{
publicstaticvoidmain(String[]args){
Othero=newOther();
newSomething().addOne(o);
}
publicvoidaddOne(finalOthero){
o.i++;
}
}
classOther{
publicinti;
}
和上面的很相似,都是关于final的问题,这有错吗?
答案:正确。在addOnemethod中,参数o被修饰成final。如果在addOnemethod里我们修改了o的reference
(比如:o=newOther();),那么如同上例这题也是错的。但这里修改的是o的membervairable
(成员变量),而o的reference并没有改变。
6.
classSomething{
inti;
publicvoiddoSomething(){
System.out.println("i="+i);
}
}
有什么错呢?看不出来啊。
答案:正确。输出的是"i=0"。inti属於instantvariable(实例变量,或叫成员变量)。instantvariable有defaultvalue。int的defaultvalue是0。
7.
classSomething{
finalinti;
publicvoiddoSomething(){
System.out.println("i="+i);
}
}
和上面一题只有一个地方不同,就是多了一个final。这难道就错了吗?
答案:错。finalinti是个final的instantvariable(实例变量,或叫成员变量)。final的instantvariable没有defaultvalue,必须在constructor(构造器)结束之前被赋予一个明确的值。可以修改为"finalinti=0;"。
8.
publicclassSomething{
publicstaticvoidmain(String[]args){
Somethings=newSomething();
System.out.println("s.doSomething()returns"+doSomething());
}
publicStringdoSomething(){
return"Dosomething...";
}
}
看上去很完美。
答案:错。看上去在main里calldoSomething没有什么问题,毕竟两个methods都在同一个class里。但仔细看,main是static的。staticmethod不能直接callnon-staticmethods。可改成"System.out.println("s.doSomething()returns"+s.doSomething());"。同理,staticmethod不能访问non-staticinstantvariable。
9.
此处,Something类的文件名叫OtherThing.java
classSomething{
privatestaticvoidmain(String[]something_to_do){
System.out.println("Dosomething...");
}
}
这个好像很明显。
答案:正确。从来没有人说过Java的Class名字必须和其文件名相同。但publicclass的名字必须和文件名相同。
10.
interfaceA{
intx=0;
}
classB{
intx=1;
}
classCextendsBimplementsA{
publicvoidpX(){
System.out.println(x);
}
publicstaticvoidmain(String[]args){
newC().pX();
}
}
答案:错误。在编译时会发生错误(错误描述不同的JVM有不同的信息,意思就是未明确的x调用,两个x都匹配(就象在同时importjava.util和java.sql两个包时直接声明Date一样)。对于父类的变量,可以用super.x来明确,而接口的属性默认隐含为publicstaticfinal.所以可以通过A.x来明确。
11.
interfacePlayable{
voidplay();
}
interfaceBounceable{
voidplay();
}
interfaceRollableextendsPlayable,Bounceable{
Ballball=newBall("PingPang");
}
classBallimplementsRollable{
privateStringname;
publicStringgetName(){
returnname;
}
publicBall(Stringname){
this.name=name;
}
publicvoidplay(){
ball=newBall("Football");
System.out.println(ball.getName());
}
}
这个错误不容易发现。
答案:错。"interfaceRollableextendsPlayable,Bounceable"没有问题。interface可继承多个interfaces,所以这里没错。问题出在interfaceRollable里的"Ballball=newBall("PingPang");"。任何在interface里声明的interfacevariable(接口变量,也可称成员变量),默认为publicstaticfinal。也就是说"Ballball=newBall("PingPang");"实际上是"publicstaticfinalBallball=newBall("PingPang");"。在Ball类的Play()方法中,"ball=newBall("Football");"改变了ball的reference,而这里的ball来自Rollableinterface,Rollableinterface里的ball是publicstaticfinal的,final的object是不能被改变reference的。因此编译器将在"ball=newBall("Football");"这里显示有错。
28、设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。写出程序。
以下程序使用内部类实现线程,对j增减的时候没有考虑顺序问题。
publicclassThreadTest1{
privateintj;
publicstaticvoidmain(Stringargs[]){
ThreadTest1tt=newThreadTest1();
Incinc=tt.newInc();
Decdec=tt.newDec();
for(inti=0;i<2;i++){
Threadt=newThread(inc);
t.start();
t=newThread(dec);
t.start();
}
}
privatesynchronizedvoidinc(){
j++;
System.out.println(Thread.currentThread().getName()+"-inc:"+j);
}
privatesynchronizedvoiddec(){
j--;
System.out.println(Thread.currentThread().getName()+"-dec:"+j);
}
classIncimplementsRunnable{
publicvoidrun(){
for(inti=0;i<100;i++){
inc();
}
}
}
classDecimplementsRunnable{
publicvoidrun(){
for(inti=0;i<100;i++){
dec();
}
}
}
}