Thinking in Java

Chapter 2 Everything is an Objec

2018-10-06  本文已影响0人  綿綿_

You manipulate the objects with references

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

The keyword new says, “Make me a new one of these objects.”

String s = new String("asdf");

it also means supplying an initial character string.

Where the storage lives

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 & C++, on the other hand, allow you to suggest register allocation to the compiler).
2. The stack.
This lives in the general random-access 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.

3. The heap. This is a general-purpose pool of memory (also in the RAM are) where all Java objects live. The nice thing about the heap is that, unlike the stack, the compiler doesn’t need to know how long that storage must stay on the heap. Thus, there’s a great deal of flexibility in using storage on the heap. Whenever you need an object, you simply write the code to create it by using new, and the storage is allocated on the heap when that code is executed. Of course there’s a price you pay for this flexibility: It may take more time to allocate and clean up heap storage than stack storage (if you even could create objects on the stack in Java, as you can in C++).
4. Constant storage. Constant values are often placed directly in the program code, which is safe since they can never change. Sometimes constants are cordoned off by themselves so that they can be optionally placed in read-only memory (ROM), in embedded systems.2
5. Non-RAM storage.
If data lives completely outside a program, it can exist while the program is not running, outside the control of the program. The two primary examples of this are streamed objects, in which objects are turned into streams of bytes, generally to be sent to another machine, and persistent objects, in which the objects are placed on disk so they will hold their state even when the program is terminated. The trick with these types of storage is turning the objects into something that can exist on the other medium, and yet can be resurrected into a regular RAMbased object when necessary. Java provides support for lightweight persistence, and mechanisms such as JDBC and Hibernate provide more sophisticated support for
storing and retrieving object information in databases.

Special case : primative types

1.For primitive types , 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.

2.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.

3,All numeric types are signed

4.The “wrapper” classes for the primitive data types allow you to make a non-primitive 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;

5.High-precision numbers

BigInteger supports arbitrary-precision integers. This means that you can accurately represent integral values of any size without losing any information during operations.

BigDecimal is for arbitrary-precision fixed-point numbers;

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.

Arrays in Java

When you create an array of objects, you are really creating an array of references, and each of those references is automatically initialized to a special value with its own keyword: null.
When Java sees null, it recognizes that the reference in question isn’t pointing to an object. You must assign an object to each reference before you use it, and if you try to use a reference that’s still null, the problem will be reported at run time.

You never need to destory an object

Scoping

The extra spaces, tabs, and carriage returns do not affect the resulting program.

Scope of Objects

Java objects do not have the same lifetimes as primitives. When you create a Java object using new, it hangs around past the end of the scope.

Java has a garbage collector, which looks at all the objects that were created with new and figures out which ones are not being referenced anymore. Then it releases the memory for those objects.This eliminates memory leak.

Creating a new data type : class

For example:

class ATypeName { /* Class body goes here */ }

you can create an object of this type using new:

ATypeName a = new ATypeName(); 

Fields and methods

an example of a class with some fields:

class DataOnly { 
int i;
double d;
boolean b;
}

You can assign values to the fields

DataOnly data = new DataOnly(); 

data.i = 47; 
data.d = 1.1;
data.b = false;

It is also possible that your object might contain other objects that contain data you’d like to modify. For this, you just keep “connecting the dots.” For example:

myPlane.leftTank.capacity = 100;

Default values for primitive members

When a primitive data type is a member of a class, it is guaranteed to get a default value if you do not initialize it:

This guarantee doesn’t apply to local variables—those that are not fields of a class. (for example: a filed in a method)

Methods, arguments, and return values

basic form of methods:

ReturnType methodName( /* Argument list */ ) { /* Method body */
}

You call a method for an object by naming the object followed by a period (dot), followed by the name of the method and its argument list, like this:

objectName.methodName(arg1, arg2, arg3);

for example:

int x = a.f();
// f() is the method
// a is the object

The argument list

The method argument list specifies what information you pass into the method.

int storage(String s) { 
return s.length() * 2;
//s is the argument of type String
// s is called
//length() method is called
}

Building a Java program

Name visibility

Java makes all of your files automatically live in their own namespaces, and each class within a file must have a unique identifier—the language prevents name clashes for you.

Using other components

Import tells the compiler to bring in a package, which is a library of classes. (In other languages, a library could consist of functions and data as well as classes, but remember that
all code in Java must be written inside a class.
)

for example:

import java.util.*;

The static keyword

An important use of static for methods is to allow you to call that method without creating an object.

When you say something is static, it means that particular field or method is not tied to any particular object instance of that class.So even if you’ve never created an object of that class you can call a static method or access a static field. With ordinary, non-static fields and methods, you must create an object and use that object to access the field or method, since non-static fields and methods must know the particular object they are working with.

class StaticTest { 
static int i = 47;
}

Now even if you make two StaticTest objects, there will still be only one piece of storage for StaticTest.i. Both objects will share the same i. Consider:

StaticTest st1 = new StaticTest();
StaticTest st2 = new StaticTest();

both st1.i and st2.i have the same value of 47 since they refer to the same piece of memory.

Two ways to refer to a static variable:

st2.i

or you can:

StaticTest.i++; 

The ++ operator adds one to the variable. At this point, both st1.i and st2.i will have the value 48.

Define a static method:

class Incrementable { 
static void increment()
 { 
StaticTest.i++;
 }
}

You can call increment( ) in the typical way, through an object:

Incrementable sf = new Incrementable(); 
sf.increment();

Or, because increment( ) is a static method, you can call it directly through its class:

Incrementable.increment();

Coding style

Capitalize the first letter of a class name. If the class name consists of several words, they are run together (that is, you don’t use underscores to separate the names), and the first letter of each embedded word is capitalized, such as:

class AllTheColorsOfTheRainbow { // ...

This is sometimes called “camel-casing.”
For almost everything else—methods, fields (member variables), and object reference names—the accepted style is just as it is for classes except that the first letter of the identifier is lowercase. For example:

class AllTheColorsOfTheRainbow { 
int anIntegerRepresentingColors; 
void changeTheHueOfTheColor(int newHue) {
 // ...
} 
// ... 
} 
上一篇下一篇

猜你喜欢

热点阅读