Question | Mean Score | StdDev | Question | Mean Score | StdDev | |
---|---|---|---|---|---|---|
1 | 7 | 5 | 9 | 2 | 6 | |
2 | 4 | 6 | 10 | 3.2 | 5.8 | |
3 | 7 | 4 | 11 | 7.1 | 4.6 | |
4 | 1 | 5 | 12 | 7.4 | 4.5 | |
5 | 1.3 | 5.6 | 13 | 2.3 | 5.4 | |
6 | 7 | 3 | 14 | 5.3 | 5.6 | |
7 | 1.7 | 6.2 | 15 | 6.5 | 4.4 | |
8 | 4 | 5 | Total | 68.4 | 26.5 |
Assume that the following classes have been defined.
public class Basic {
public void printIt() { System.out.println("Basic method"); }
}
public class Extended extends Basic {
public void printIt() { System.out.println("Extended method"); }
}
If the following line of code is executed, what is printed?
new Extended().printIt();
The correct answer is d. The class Extended overrides Basic's printIt() method. Since method lookup is always outside-in, the new Extended's extended printIt() is found before its basic printIt(). Execution of the extended printIt() ends without calling the basic printIt(). (Only constructors automatically invoke superclass functionality.)
If we have already declared
boolean isHappy = false;
then the problem with the expression
isHappy == true
is that
The correct answer is a. It is redundant to compare a boolean to true; isHappy is true, or it isn't, all by itself. The expression isHappy has the same type and value as isHappy = true.
As to the other answers: The == operator doesn't change the value of isHappy; Java assignment uses a single =. There's nothing wrong with the declaration of isHappy, and true is a Java (boolean) literal (and a keyword).
If we are inside the act method of a NodeBehavior with parameters ins and outs -- that is, inside a method with the declaration
public void act( ChannelInputStream[] ins, ChannelOutputStream[] outs)
-- and ChannelInputStream has a readObject method specified as
public Object readObject() throws ChannelEmptyException, ChannelDisabledException;
then the type of the expression ins[3].readObject() is
The correct answer is d. ins is of type ChannelInputStream[] (array of ChannelInputStreams). ins[3] refers to the 4th ChannelInputStream in ins. (Remember, Java arrays start at 0.) So the type of ins[3] is ChannelInputStream. Each ChannelInputStream has a readObject() method. The type returned by this method is Object; you can tell that from its declaration. The type of a method invocation expression is the return type of the method. So ins[3].readObject() is an expression with type Object.
Which of the following could be a legal Java constructor method for class Classic? You may assume that Classic defines any necessary methods or fields.
The correct answer is d. Answer a is missing the parentheses after the constructor name. Answer b has a return type; constructors don't. Answer c calls super(); in its second line. If super(); is present, it must be the first line of the constructor. Answer e has a return, which constructors don't. Answer f has the same problem: a return. Also, you can't invoke a constructor (new Classic()) inside that constructor (Classic()).
Assume that the following class has been defined:
public class Test { // line 1
private String name; // line 2
public Test ( String name ) { // line 3 this.name = name; // line 4 } // line 5
public String getName() { // line 6 return this.name; // line 7 } // line 8
public void setName( String newName) { // line 9 this.name = newName; // line 10 } // line 11
} // line 12
Which of the following statements is true?
The correct answer is e.
Answer a is incorrect because new Test() is not a legal expression, given this class definition. class Test has an explicitly defined constructor, and that constructor requires a parameter.
Answer b is simply wrong: Line 4 is perfectly legitimate Java and a common way of initializing a field.
Answer c misses the fact that setName is public, while name is private. This means that objects other than Tests can't use name directly.
Answer d would mean that a Test and a String had the same value; since neither is a subclass of the other, this isn't possible.
Answer e is correct: foo's binding doesn't change, though the object it is bound to (the thing it labels) has one of its labels change.
Answer f is false because foo.name is legal inside the Test class.
Assume that the following class has been defined:
public class Test { // line 1
private String name; // line 2
public Test ( String name ) { // line 3 this.name = name; // line 4 } // line 5
public String getName() { // line 6 return this.name; // line 7 } // line 8
public void setName( String newName) { // line 9 this.name = newName; // line 10 } // line 11
} // line 12
(This definition is identical to that in Question 5.)
Further, assume that the following lines of code are executed in order.
Which of the following statements is true?
The correct answer is f.
Answer a is false: secondTest is used to label a new Test object on line 5, and nothing on line 6 changes that.
Answer b is incorrect because fourthTest is assigned the value of firstTest on line 6. On line 4, firstTest gets the value of secondTest. But secondTest has never been given a value, so it is not stuck on anything, i.e., it is null. This means that line 4 makes firstTest null, and line 6 makes fourthTest null.
Line 4 has nothing to do with thirdTest.
There are three objects created in this sequence, one by each invocation of new Test(...) -- on lines 1, 3, and 5.
The object labeled by firstTest after line 1 is a new Test object. The object labeled by secondTest after line 5 is another new Test object. Each invocation of new Test( ... ) creates a brand new, never-before-seen instance of Test.
After line 2, the value of secondTest does not change until line 5. Line 4 sticks the firstTest label onto the object currently referred to by secondTest, i.e., the value that secondTest was assigned (or not assigned) on line 2.
Assume that the following interface has been defined:
public interface Laughable {
public String laugh( String sound, int n );
}
Which of the following is not a legitimate definition?
The correct answer is e. In order to implement Laughable, a class must have a method that is called laugh, takes a String and an int (in that order, but with any names), and returns a String.
Chuckler may be rather roundabout, but it successfully implements the Laughable interface.
Chortler does too. It uses the "stupid + trick" to concatenate Strings.
Santa's laugh method doesn't take the right parameters, but that's OK: Santa doesn't promise to implement Laughable.
Multilaugher implements Laughable successfully: its laugh method takes a String and an int and returns a String.
Giggler doesn't implement Laughable: its laugh method returns void, violating the interface specification.
Cackler successfully implements both laugh and run. It is a legitimate definition.
Assume that the following declarations apply:
boolean isSunny = true; int i = 0;
Which of the following Java fragments has the value true ?
The correct answer is d. Answers a and e are statements, not expressions; statements do not have values. Answer b is a type error: you can't use logical negation (!) with an int, only with a boolean. Answer c is of type boolean, but its value is false. (Adding 3 to i will make it larger, not smaller, than itself.) Answer f is an expression with type int, not boolean: it is a cast expression. Only answer d has type boolean and value true.
Consider the following class definition:
public class BadFields {
private int myNum = this.lastNumDefined;
public String = "Hello, World!";
public int anotherNum, lastNumDefined;
}
Which of the following statements is true?
The correct answer is b. myNum's definition is legitimate, even though it refers to lastNumDefined, which isn't defined until later. All fields and methods (of the same class) are visible to one another. anotherNum and lastNumDefined are also legitimate; this is the two-names-for-one-definition form. But the String field doesn't have a name, so the declaration is not valid.
public class Fred {
private String name = "Fred";
public String getName () { return this.name(); }
public void otherMethod ( String name ) { System.out.println( this.name ); }
}
public class Barney {
public void barneyMethod () { Fred fred = new Fred(); System.out.println( this.name ); System.out.println( fred.name ); System.out.println( Fred.name ); }
}
Which of the following statements is true?
The correct answer is f. The references to this.name in Fred's class are both legal. this.name refers to Fred's name field, regardless of the names of parameters or local variables. And within the Fred class, it doesn't matter if name has been defined to be private.
The references to name in Barney's methods are not legal, though. this.name would refer to Barney's name field; but Barney doesn't have one. fred.name refers to the Fred object bound to the local variable fred, but Fred objects' name fields are private. Fred.name would refer to the static field of the Fred class, but name is not a static field.
Consider the following code:
public class SomeClassOrOther {
Not a comment. 0
// A possible comment. 1 Another possible comment. 2 Yet another //possible comment. 3 // Still another possible comment. 4
/* A possible comment. 5 Another possible comment . 6 Yet another //possible comment. 7 // Still another possible comment. 8 /* Even more possible comment. 9 */ Final possible comment. 10 */
}
Some of these lines are commented out. Others may be partially commented out, or not commented out at all. For example, 0 refers to a line that is not a comment.
Which one of the following sets of numbers includes only lines that are fully commented out?
The correct answer is b. Line 1 is fully commented out . Line 2 is not: // comments only comment out the remainder of the line that they are on. Line 3 is partially commented out: Yet another is not commented out, but possible comment is. Line 4 is again fully commented out.
/* comments, unlike // comments, persist for multiple lines. In fact, they continue until the first */, regardless of //s. However, they don't nest: no matter how many /*s you have, the first */ ends the comment. So lines 5-9 are commented out (fully), but line 10 is not.
Consider the following code:
public class AnotherClass {
private int myNumber;
public int returnNumber( int aNumber ) { return something; }
public int magicNumber( int anotherNumber ){ return anotherNumber; }
}
The return statement in the returnNumber method is missing its return expression. Which one of the following is not a legitimate expression to be returned by returnNumber? (Cross out each of the choices that could legitimately be used to replace something in the return statement.)
The correct answer is e. The only requirement on somethingis that it must be a legitimate expression with type int. 42 is. this.myNumber refers to the field, which has type int. aNumber refers to the parameter, which has type int. this.magicNumber() invokes a method, which has return type int.And Math.round( float ) returns int. But anotherNumber is a parameter to magicNumber(), not to returnNumber() -- its name is not accessible within returnNumber.
Consider the following class definition:
public class AnimateObject implements Runnable {
private Thread spirit;
public AnimateObject() { this.spirit = new Thread( this ); this.spirit.start(); }
public void run(){ while( true ){ System.out.println("I'm here!"); } }
}
Which one of the following statements is false? (Cross out the true statements.)
The correct answer is f.
A is self-explanatory and true.
B is also true. If this change were made, AnimateObjects would not have access to their Threads outside of their constructors, but the code would still behave in the same way.
C is true because the run method will run away!
D is true because the Thread constructor requires that its argument be a Runnable.
E is true because that is what a Thread's start() method does.
F is false because the call to start() returns no matter what. It is the new Thread (this.spirit) that gets caught up in the infinite run loop.
Assume the following definitions:
int i = 3; long l = 7; double d = 5;
Which of the following statements causes a type casting exception? You may assume that each line is independent, i.e., they are not executed one after the other.
The correct answer is a. Remember: byte to short to int to long to float to double. This direction can be done automagically, but the other way requires explicit intervention.
A is invalid because after i is cast to double, it is too wide to be automatically cast to long.
B is valid: long to double explicitly is OK, then double to double implicitly is OK.
C is valid: into to long explicitly is OK, then long to double implicitly.
D involves only a (legal) implicit widening from int to long.
E involves an explicit narrowing of a double to an int. This is dangerous (and possibly lossy), but perfectly legitimate Java. Once we have an int -- and the type of the expression (int) d is int -- then widening to a long is no problem. (Java doesn't care that the int used to be a double.)
Similarly, the narrowing cast from long to int in F is dangerous, but legal; the widening cast back to long won't restore lost information, but it is still legitimate Java.
Assume the following definitions:
public interface Laughable { public String laugh( String sound, int n ); }
public class BaseClass implements Laughable {
public String laugh (String sound, int n) { return sound; }
}
public class Polytipic extends BaseClass implements Runnable {
private Thread spirit;
public Polytipic() { this.spirit = new Thread( this ); this.spirit.start(); }
public void run() {}
}
Now, assume that we declare
SomeType polyanna = new Polytipic();
Which of the following could not be used as a replacement for SomeType in this declaration? (Cross out the choices that would be legitimate types for SomeType.)
The correct answer is f. Any type that is a legitimate type for Polytipic can be used as a substitute for SomeType. Polytipic extends BaseClass and implements Runnable, so a PolyTypic is a Polytypic, a BaseClass, and a Runnable. Since BaseClass implements Laughable, every BaseClass instance is also a Laughable; a Polytypic is a BaseClass, so it's a Laughable. Since BaseClass doesn't explicitly extend another class, it implicitly extends Object, so a Polytypic is an Object, too. (Everything that isn't an int, short, byte, long, char, double, float, boolean, or void is an Object.)
But a Polytypic isn't a Thrread; it just has one.
This course is a part of Lynn Andrea Stein's Rethinking CS101 project at the MIT AI Lab and the Department of Electrical Engineering and Computer Science at the Massachusetts Institute of Technology.
Last modified: Mon Oct 13 13:52:58 1997