Exploring the Basic APIs Part

1. Reflection is a third form of runtime type identification. Applications use reflection to learn about loaded classes, interfaces, enums (a kind of class), and annotation types (a kind of interface); and to instantiate classes, call methods, access fields, and perform other tasks reflectively.

2. The difference between Class's getDeclaredFields() and getFields() methods is as follows: getDeclaredFields() returns an array of Field objects representing all public, protected, default (package) access, and private fields declared by the class or interface represented by this Class object while excluding inherited fields, whereas getFields() returns an array of Field objects representing public fields of the class or interface represented by this Class object, including those public fields inherited from superclasses and superinterfaces.

3. You would determine if the method represented by a Method object is abstract by calling the object's getModifiers() method, bitwise ANDing the return value with Modifier.ABSTRACT, and comparing the result with Modifier.ABSTRACT. For example, ((method.getModifiers() & Modifier.ABSTRACT) == Modifier.ABSTRACT) evaluates to true when the method represented by the Method object whose reference is stored in method is abstract.

4. The three ways of obtaining a Class object are to use Class's forName() method, Object's getClass() method, and a class literal.

5. The answer is true: a string literal is a String object.

6. The purpose of String's intern() method is to store a unique copy of a String object in an internal table of String objects. intern() makes it possible to compare strings via their references and == or !=. These operators are the fastest way to compare strings, which is especially valuable when sorting a huge number of strings.

7. String and StringBuffer differ in that String objects contain immutable sequences of characters, whereas StringBuffer objects contain mutable sequences of characters.

8. StringBuffer and StringBuilder differ in that StringBuffer methods are synchronized, whereas StringBuilder's equivalent methods are not synchronized. As a result, you would use the thread-safe but slower StringBuffer class in multithreaded situations and the nonthread-safe but faster StringBuilder class in single-threaded situations.

9. System's arraycopy() method copies all or part of one array's elements to another array.

10. A thread is an independent path of execution through an application's code.

11. The purpose of the Runnable interface is to identify those objects that supply code for threads to execute via this interface's solitary public void run() method.

12. The purpose of the Thread class is to provide a consistent interface to the underlying operating system's threading architecture. It provides methods that make it possible to associate code with threads, as well as to start and manage those threads.

13. The answer is false: a Thread object associates with a single thread.

14. A race condition is a scenario in which multiple threads update the same object at the same time or nearly at the same time. Part of the object stores values written to it by one thread, and another part of the object stores values written to it by another thread.

15. Synchronization is the act of allowing only one thread at time to execute code within a method or a block.

16. Synchronization is implemented in terms of monitors and locks.

17. Synchronization works by requiring that a thread that wants to enter a monitor-controlled critical section first acquire a lock. The lock is released automatically when the thread exits the critical section.

18. The answer is true: variables of type long or double are not atomic on 32-bit virtual machines.

19. The purpose of reserved word volatile is to let threads running on multiprocessor or multicore machines access a single copy of an instance field or class field. Without volatile, each thread might access its cached copy of the field and will not see modifications made by other threads to their copies.

20. The answer is false: Object's wait() methods cannot be called from outside of a synchronized method or block.

21. Deadlock is a situation where locks are acquired by multiple threads, neither thread holds its own lock but holds the lock needed by some other thread, and neither thread can enter and later exit its critical section to release its held lock because some other thread holds the lock to that critical section.

22. The purpose of the ThreadLocal class is to associate per-thread data (such as a user ID) with a thread.

23. InheritableThreadLocal differs from ThreadLocal in that the former class lets a child thread inherit a thread-local value from its parent thread.

24. Listing 31 presents a more efficient version of Listing 6-14's image names loop.

Listing 31. A more efficient image names loop

String[] imageNames = new String[NUM_IMAGES]; StringBuffer sb = new StringBuffer();

sb.append("image"); sb.append(i); sb.append(".gif"); imageNames[i] = sb.toString();

sb.setLength(0); // Erase previous StringBuffer contents.

25. Listing 32 presents the Classify application that was called for in Chapter 7. Listing 32. Classifying a command-line argument as an annotation type, enum, interface, or class public class Classify {

public static void main(String[] args) {

System.err.println("usage: java Classify pkgAndTypeName"); return;

Class<?> clazz = Class.forName(args[0]); if (clazz.isAnnotation())

System.out.println("Annotation"); else if (clazz.isEnum())

System.out.println("Enum"); else if (clazz.isInterface())

System.out.println("Interface"); else

System.out.println("Class");

catch (ClassNotFoundException cnfe) {

System.err.println("could not locate " + args[0]);

Specify java Classify java.lang.Override and you will see Annotation as the output. Also, java.Classify java.math.RoundingMode outputs Enum, java Classify java.lang.Runnable outputs Interface, and java Classify java.lang.Class outputs Class.

26. Listing 33 presents the revised ExploreType application that was called for in Chapter 7.

Listing 33. An improved ExploreType application public class ExploreType {

public static void main(String[] args) {

System.err.println("usage: java ExploreType pkgAndTypeName"); return;

Class<?> clazz = Class.forName(args[0]); if (clazz.isAnnotation()) dumpAnnotation(clazz); else if (clazz.isEnum()) dumpEnum(clazz); else if (clazz.isInterface()) dumpInterface(clazz); else dumpClass(clazz);

catch (ClassNotFoundException cnfe) {

System.err.println("could not locate " + args[0]);

public static void dumpAnnotation(Class clazz) {

// Left blank as an exercise for you to complete.

public static void dumpClass(Class clazz) {

// Output class header.

int modifiers = clazz.getModifiers();

if ((modifiers & Modifier.PUBLIC) == Modifier.PUBLIC)

System.out.print("public "); if ((modifiers & Modifier.ABSTRACT) == Modifier.ABSTRACT)

System.out.print("abstract "); System.out.println("class " + clazz.getName()); System.out.println("{");

// Output fields.

System.out.println (" // FIELDS"); Field[] fields = clazz.getDeclaredFields();

System.out.print(" "); System.out.println(fields[i]);

System.out.println();

// Output constructors.

System.out.println (" // CONSTRUCTORS");

Constructor[] constructors = clazz.getDeclaredConstructors();

System.out.print(" "); System.out.println(constructors[i]);

System.out.println(); // Output methods.

System.out.println (" // METHODS"); Method[] methods = clazz.getDeclaredMethods();

System.out.print(" "); System.out.println(methods[i]);

// Output class trailer. System.out.println("}");

public static void dumpEnum(Class clazz)

// Left blank as an exercise for you to complete.

public static void dumpInterface(Class clazz)

// Left blank as an exercise for you to complete.

I have deliberately written this application so that it can be expanded to output annotation types, enums, and interfaces.

27. Listing 34 presents the revised CountingThreads application that was called for in Chapter 7.

Listing 34. Counting via daemon threads public class CountingThreads {

public static void main(String[] args) {

^Override public void run() {

String name = Thread.currentThread().getName(); int count = 0; while (true)

System.out.println(name + ": " + count++);

Thread thdA = new Thread(r); thdA.setDaemon(true); Thread thdB = new Thread(r); thdB.setDaemon(true); thdA.start(); thdB.start();

When you run this application, the two daemon threads start executing and you will probably see some output. However, the application will end as soon as the default main thread leaves the main() method and dies.

28. Listing 35 presents the StopCountingThreads application that was called for in Chapter 7.

Listing 35. Stopping the counting threads when Enter is pressed public class StopCountingThreads {

private static volatile boolean stopped = false;

public static void main(String[] args) {

^Override public void run() {

String name = Thread.currentThread().getName(); int count = 0; while (!stopped)

System.out.println(name + ": " + count++);

Thread thdA = new Thread(r); Thread thdB = new Thread(r); thdA.start(); thdB.start();

try { System.in.read(); } catch (IOException ioe) {} stopped = true;

Was this article helpful?

0 0

Post a comment