【文章內容簡介】
object connected to it. So if you want to hold a word or sentence, you create a String reference: But here you?ve created only the reference, not an object. If you decided to send a message to s at this point, you?ll get an error because s isn?t actually attached to anything (there?s no television). A safer practice, then, is always to initialize a reference when you create it:String s = asdf。However, this uses a special Java feature: Strings can be initialized with quoted text. Normally, you must use a more general type of initialization for objects. You must create all the objects When you create a reference, you want to connect it with a new object. You do so, in general, with the new operator. The keyword new says, “Make me a new one of these objects.” So in the preceding example, you can say:String s = new String(asdf)。Not only does this mean “Make me a new String,” but it also gives information about how to make the String by supplying an initial character string. Of course, Java es with a plethora of readymade types in addition to String. What?s more important is that you can create your own types. In fact, creating new types is the fundamental activity in Java programming, and it?s what you?ll be learning about in the rest of this book.. Where storage lives It?s useful to visualize some aspects of how things are laid out while the program is running—in particular how memory is arranged. There are five different places to store data: 1. Registers. This is the fastest storage because it exists in a place different from that of other storage: inside the processor. However, the number of registers is severely limited, so registers are allocated as they are needed. You don?t have direct control, nor do you see any evidence in your programs that registers even exist (C amp。 C++, on the other hand, allow you to suggest register allocation to the piler). 2. The stack. This lives in the general randomaccess memory (RAM) area, but has direct support from the processor via its stack pointer. The stack pointer is moved down to create new memory and moved up to release that memory. This is an extremely fast and efficient way to allocate storage, second only to registers. The Java system must know, while it is creating the program, the exact lifetime of all the items that are stored on the stack. This constraint places limits on the flexibility of your programs, so while some Java storage exists on the stack—in particular, object references—Java objects themselves are not placed on the stack. Special case: primitive types One group of types, which you?ll use quite often in your programming, gets special treatment. You can think of these as “primitive” types. The reason for the special treatment is that to create an object with new—especially a small, simple variable—isn?t very efficient, because new places objects on the heap. For these types Java falls back on the approach taken by C and C++. That is, instead of creating the variable by using new, an “automatic” variable is created that is not a reference. The variable holds the value directly, and it?s placed on the stack, so it?s much more efficient. Java determines the size of each primitive type. These sizes don?t change from one machine architecture to another as they do in most languages. This size invariance is one reason Java programs are more portable than programs in most other numeric types are signed, so don?t look for unsigned size of the boolean type is not explicitly specified。 it is only defined to be able to take the literal values true or “wrapper” classes for the primitive data types allow you to make a nonprimitive object on the heap to represent that primitive type. For example: char c = ?x?。 Character ch = new Character(c)。 Or you could also use: Character ch = new Character(?x?)。 Java SE5 autoboxing will automatically convert from a primitive to a wrapper type: Character ch = ?x?。 and back:char c = ch。 The reasons for wrapping primitives will be shown in a later chapter. Highprecision numbers Java includes two classes for performing highprecision arithmetic: BigInteger and BigDecimal. Although these approximately fit into the same category as the “wrapper” classes, neither one has a primitive classes have methods that provide analogues for the operations that you perform on primitive types. That is, you can do anything with a BigInteger or BigDecimal that you can with an int or float, it?s just that you must use method calls instead of operators. Also, since there?s more involved, the operations will be slower. You?re exchanging speed for accuracy. BigInteger supports arbitraryprecision integers. This means that you can accurately represent integral values of any size without losing any information during operations. BigDecimal is for arbitraryprecision fixedpoint numbers。 you can use these for accurate moary calculations, for example. Consult the JDK documentation for details about the constructors and methods you can call for these two classes. Arrays in Java Virtually all programming languages support some kind of arrays. Using arrays in C and C++ is perilous because those arrays are only blocks of memory. If a program accesses the array outside of its memory block or uses the memory before initialization (mon programming errors), there will be unpredictable results. One of the primary goals of Java is safety, so many of the problems that plague programmers in C and C++ are not repeated in Java. A Java array is guaranteed to be initialized and cannot Thinking in Java be accessed outside of its range. The range checking es at the price of having a small amount of memory overhead on each array as well as verifying the index at run time, but the assumption is that the safety and increased productivity are worth the expense (and Java can sometimes op