Thinking in Java,Fourth Edition,Java 编程思想,第四版学习笔记

---恢复内容开始---

  Both C++ and Java are hybird languages.

  A hybird language allow multiple programming styles

    The reason C++ is hybird is to support backward compatibility with the C langguage (a superset of the C language)

  The Java language assumes that you want to do only object-oriented programming. It make that is simpler to learn and to user Java than many other OOP languages.

You manipulate objects with references

  You might imagine a television (the object) and a remote control ( the reference)

  Also, the remote control can stand on its own, with no television (null)

  String s; // only created a reference, not an object

  String s = "asdf"; // create a reference, and initialize the reference.

  this uses a special Java feature: String can be initialized with quoted text

You must create all the objects

  String s = new String("asdf"); // create a reference, and initialize the reference by create a new String object, and also gives information about how to create the String by supplying an initial character string.

Where storage lives

  The are five different places to store data:

    1. Registers(寄存器). Registers are allocated as they are needed. You don't have direct control.

    2. The stack (栈区). This lives in the general 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.

      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.

      In particular, object references exists on the stack, and Java objects are not placed on the stack.

    3. The heap(堆区). This is a general-purpose pool of memory (also in the RAM area) where all Java objects live. The compiler doesn't need to know how long that storage must stay on the heap. There is a great deal of flexibility in using storage on the heap, of course there is a price you pay for this flexibility: It may take more time to allocate and clean up heap storage than stack storage

    4. Constant storage.Sometimes constants are cordoned off by themselves so that they can be optionally placed in ROM in embedded systems. 例子:字符串池

    5. Non-RAM storage. Data lives completely outside a program.

      streamed objects

      persistent objects.

      Java provides support for lightweight persistence. Such as JDBC and Hibernate provide more sophisticated support for storing and retrieving object information in databases.

Special case: 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. an "automatic" variable is created. The variable holds the value directly, and it's placed on the stack,so it's much more efficient.

  Java detemines the size of each primitive type. These size don't changed from one machine architecture to another as they do in most languages

  原始类型  包装类型   Size

  boolean   Boolean   -

  char    Character  16bits

  byte    Byte     8bits

  short    Short    16bits

  int     Integer   32bits

  long    Long    64bits

  float    Float    32bits

  double   Double   64bits

  void    Void     -

  All numeric tyeps are signed 

  The size of the boolean type is not explicitly specified; it is only defined to be able to take the literal values true or false.

  The "wrapper" classes for the primitive data types allow you to make a non-primitive object on the heap to represent that primitive type.

  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;

High-precision numbers

  BigInteger and BigDecimal 

  Both classes have methods that provide analogues for the operations that you perform on primitive types.

  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 support arbitrary-precision integers.

  BigDecimal supoort arbitrary-precision fixed-point numbers.

Arrays in Java

  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 (common programming errors), there will be unpredictable results.

  One of the primary goals of Java is safety. A Java array is guaranteed to be initialized and cannot be accessed outside of its range. The range checking 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.

  When you create an array of objects, you are really creating an array of references, and each of those reference is automatically initialized to a special value with its own keyword: null

  You can also create an array of primitives. Again, the compiler guarantees initialization because it zeroes the memory for that array.

You never need to destroy an object

  In most programming languages, the concept of the lifetime of a variable occupies a significant portion of the programming effort. Confusion over variable lifetimes can lead to a lot of bugs. Java simplifies the issue by doing all the cleanup work for you.

  Scoping

  It determines both the visibility and lifetime of the names defined within the scope.

  {

    int x = 12;

    {

      int x = 96; // Illegal in Java(the java designers thought that it led to confusing programs),

            // but the C and C++ will "hide" x in the larger scope is not allowed

    }

  }

  Scope of objects

  Java objects do not have the same lifetimes as primitives.

  {

    String s = new String("a string");

  } // End of scope.

  the reference "s" vanished at the end of the scope. However, the String Object that "s" was pointing to is still occupting memory.

  It turns out that because objects created with new stay around for as long as you want them, a whole slew of C++ programming problems simply vanish in Java. In C++ you must not only make sure that the objects stay around for as long as you need them, you must also destroy the objects when you're done with them.

  Java has a garbage collector, which looks at all the objects that were create with new and figures out which ones are not being referenced anymore. Then it releases the memory for those objects. (But that may be some delay, and only release the memory, you have to release other resource by yourself )

  this eliminates a certain class of programming problem: memory leak

Creating new data types: class  

  Established a new type:

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

  Create an object of this type:

    ATypeName a = new ATypeName();

  Fields and methods

  When you define a class, you can put tow types of element in your class: fields, and methods.

  A field is an object of any type that you can talk to via its reference, or a primitive type.

  Each object keeps its own storage for its fields; ordinary fiedls are not shared among objects.

  How to refer to a member of an object: objectReference.member

  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.

  (When a primitive data type is a local variable, it will cause a compile error)

  boolean     false

  char      '\u0000'

  byte      (byte)0

  short      (short)0

  int       0

  long      0L

  float      0.0f

  double     0.0d

  This ensures that member variables of primitive types will always be initialized, reduce a source of bugs. However, this initial value may not be correct or even legal for the program you are writing. It's best to always explicitly initialize your variables.

  This guarantee doesn't apply to local variables. You are responsible for assigning an appropriate value before you use them. If you forget, you will get a compile-time error telling you the variable might not have been initialized

  Methods, arguments, and return values

  Methods in Java determine the messages an object can receive. The fundamental parts: the name, the arguements, the return type, and the body.

  ReturnType methodName( /* Argument list */ ){

    /* Method body */

  }

  The method name and argument list (Which is called the signature of the method) uniquely identify that method.

  objectReference.methodName(arg1,arg2...);

  The act of calling a method is commonly referred to as sending a message to an object.

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

  (The size of each char in a String is 16 bits, or two bytes, to support Unicode characters.)

  When the return type is void, then the return keyword is used only to exit the method, and is therefore unnecessary when you reach the end of the method.

Building a Java program

  Name visibility

  the Java creators want you to use your Internet domain name in reverse since domain names are guaranteed to be unique.

  In Java 1.0 and 1.1 the domain extension com,edu,org,net,etc., were capitalized by convention.

  Partway through the development of Java 2, however, it was discovered that this caused problems, so now the entire package name is lowercase.

  Using other components

  (Java eliminates the so-called "forward referencing" problem)

  import tell the compiler exactly what classes, tells the compiler to bring in a package, which is a library of classes.

  import java.util.ArrayList; //import a class

  import java.util.*;  // import a collection of classes

  The static keyword

  When you say somethins is static, it means that particular field or method is not tied to any particular object instance of that class.

  class data and class methods

  objectReference.staticField/staticMember or className.staticField/staicMember

  Using the class name is the preferred way to refer to a static variable. Not only does it emphasize that variable's static nature, but in some cases it gives the compiler better opportunities for optimization.

  Although static, when applied to a field, definitely changes the way the data is created (one for each class versus the non-static one for each object), when applied to a method it's not so dramatic. An important use of static for methods is to allow you to call that method without creating an object. This is essential, as you will see, in defining the main() method that is the entry point for running an application.

Your first Java program

  There is a certain libray of classes that are automatically brought intyo every Java file: java.lang.

  If you don't know the library where a particular class is, or if you want to see all of the classes, you can select "Tree" in the Java documentation. Now you can find everry single class that comes with Java. Then you can use the browser's "find" function to find the particular class.

  public static void main (String[] args){ }

  System.getProperties()

  Compiling and running

  To compile and run a Java program, you must first have a Java programming environment. (JDK)

  To run a Java program, only nedd a Java runtime environment (JRE)

  compile: javac XXXX.java

  run: java XXXX

  You can use Buildfiles and Ant command to simple the process.

---恢复内容结束---

  Both C++ and Java are hybird languages.

  A hybird language allow multiple programming styles

    The reason C++ is hybird is to support backward compatibility with the C langguage (a superset of the C language)

  The Java language assumes that you want to do only object-oriented programming. It make that is simpler to learn and to user Java than many other OOP languages.

You manipulate objects with references

  You might imagine a television (the object) and a remote control ( the reference)

  Also, the remote control can stand on its own, with no television (null)

  String s; // only created a reference, not an object

  String s = "asdf"; // create a reference, and initialize the reference.

  this uses a special Java feature: String can be initialized with quoted text

You must create all the objects

  String s = new String("asdf"); // create a reference, and initialize the reference by create a new String object, and also gives information about how to create the String by supplying an initial character string.

Where storage lives

  The are five different places to store data:

    1. Registers(寄存器). Registers are allocated as they are needed. You don't have direct control.

    2. The stack (栈区). This lives in the general 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.

      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.

      In particular, object references exists on the stack, and Java objects are not placed on the stack.

    3. The heap(堆区). This is a general-purpose pool of memory (also in the RAM area) where all Java objects live. The compiler doesn't need to know how long that storage must stay on the heap. There is a great deal of flexibility in using storage on the heap, of course there is a price you pay for this flexibility: It may take more time to allocate and clean up heap storage than stack storage

    4. Constant storage.Sometimes constants are cordoned off by themselves so that they can be optionally placed in ROM in embedded systems. 例子:字符串池

    5. Non-RAM storage. Data lives completely outside a program.

      streamed objects

      persistent objects.

      Java provides support for lightweight persistence. Such as JDBC and Hibernate provide more sophisticated support for storing and retrieving object information in databases.

Special case: 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. an "automatic" variable is created. The variable holds the value directly, and it's placed on the stack,so it's much more efficient.

  Java detemines the size of each primitive type. These size don't changed from one machine architecture to another as they do in most languages

  原始类型  包装类型   Size

  boolean   Boolean   -

  char    Character  16bits

  byte    Byte     8bits

  short    Short    16bits

  int     Integer   32bits

  long    Long    64bits

  float    Float    32bits

  double   Double   64bits

  void    Void     -

  All numeric tyeps are signed 

  The size of the boolean type is not explicitly specified; it is only defined to be able to take the literal values true or false.

  The "wrapper" classes for the primitive data types allow you to make a non-primitive object on the heap to represent that primitive type.

  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;

High-precision numbers

  BigInteger and BigDecimal 

  Both classes have methods that provide analogues for the operations that you perform on primitive types.

  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 support arbitrary-precision integers.

  BigDecimal supoort arbitrary-precision fixed-point numbers.

Arrays in Java

  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 (common programming errors), there will be unpredictable results.

  One of the primary goals of Java is safety. A Java array is guaranteed to be initialized and cannot be accessed outside of its range. The range checking 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.

  When you create an array of objects, you are really creating an array of references, and each of those reference is automatically initialized to a special value with its own keyword: null

  You can also create an array of primitives. Again, the compiler guarantees initialization because it zeroes the memory for that array.

You never need to destroy an object

  In most programming languages, the concept of the lifetime of a variable occupies a significant portion of the programming effort. Confusion over variable lifetimes can lead to a lot of bugs. Java simplifies the issue by doing all the cleanup work for you.

  Scoping

  It determines both the visibility and lifetime of the names defined within the scope.

  {

    int x = 12;

    {

      int x = 96; // Illegal in Java(the java designers thought that it led to confusing programs),

            // but the C and C++ will "hide" x in the larger scope is not allowed

    }

  }

  Scope of objects

  Java objects do not have the same lifetimes as primitives.

  {

    String s = new String("a string");

  } // End of scope.

  the reference "s" vanished at the end of the scope. However, the String Object that "s" was pointing to is still occupting memory.

  It turns out that because objects created with new stay around for as long as you want them, a whole slew of C++ programming problems simply vanish in Java. In C++ you must not only make sure that the objects stay around for as long as you need them, you must also destroy the objects when you're done with them.

  Java has a garbage collector, which looks at all the objects that were create with new and figures out which ones are not being referenced anymore. Then it releases the memory for those objects. (But that may be some delay, and only release the memory, you have to release other resource by yourself )

  this eliminates a certain class of programming problem: memory leak

Creating new data types: class  

  Established a new type:

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

  Create an object of this type:

    ATypeName a = new ATypeName();

  Fields and methods

  When you define a class, you can put tow types of element in your class: fields, and methods.

  A field is an object of any type that you can talk to via its reference, or a primitive type.

  Each object keeps its own storage for its fields; ordinary fiedls are not shared among objects.

  How to refer to a member of an object: objectReference.member

  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.

  (When a primitive data type is a local variable, it will cause a compile error)

  boolean     false

  char      '\u0000'

  byte      (byte)0

  short      (short)0

  int       0

  long      0L

  float      0.0f

  double     0.0d

  This ensures that member variables of primitive types will always be initialized, reduce a source of bugs. However, this initial value may not be correct or even legal for the program you are writing. It's best to always explicitly initialize your variables.

  This guarantee doesn't apply to local variables. You are responsible for assigning an appropriate value before you use them. If you forget, you will get a compile-time error telling you the variable might not have been initialized

  Methods, arguments, and return values

  Methods in Java determine the messages an object can receive. The fundamental parts: the name, the arguements, the return type, and the body.

  ReturnType methodName( /* Argument list */ ){

    /* Method body */

  }

  The method name and argument list (Which is called the signature of the method) uniquely identify that method.

  objectReference.methodName(arg1,arg2...);

  The act of calling a method is commonly referred to as sending a message to an object.

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

  (The size of each char in a String is 16 bits, or two bytes, to support Unicode characters.)

  When the return type is void, then the return keyword is used only to exit the method, and is therefore unnecessary when you reach the end of the method.

Building a Java program

  Name visibility

  the Java creators want you to use your Internet domain name in reverse since domain names are guaranteed to be unique.

  In Java 1.0 and 1.1 the domain extension com,edu,org,net,etc., were capitalized by convention.

  Partway through the development of Java 2, however, it was discovered that this caused problems, so now the entire package name is lowercase.

  Using other components

  (Java eliminates the so-called "forward referencing" problem)

  import tell the compiler exactly what classes, tells the compiler to bring in a package, which is a library of classes.

  import java.util.ArrayList; //import a class

  import java.util.*;  // import a collection of classes

  The static keyword

  When you say somethins is static, it means that particular field or method is not tied to any particular object instance of that class.

  class data and class methods

  objectReference.staticField/staticMember or className.staticField/staicMember

  Using the class name is the preferred way to refer to a static variable. Not only does it emphasize that variable's static nature, but in some cases it gives the compiler better opportunities for optimization.

  Although static, when applied to a field, definitely changes the way the data is created (one for each class versus the non-static one for each object), when applied to a method it's not so dramatic. An important use of static for methods is to allow you to call that method without creating an object. This is essential, as you will see, in defining the main() method that is the entry point for running an application.

Your first Java program

  There is a certain libray of classes that are automatically brought intyo every Java file: java.lang.

  If you don't know the library where a particular class is, or if you want to see all of the classes, you can select "Tree" in the Java documentation. Now you can find everry single class that comes with Java. Then you can use the browser's "find" function to find the particular class.

  public static void main (String[] args){ }

  System.getProperties()

  Compiling and running

  To compile and run a Java program, you must first have a Java programming environment. (JDK)

  To run a Java program, only nedd a Java runtime environment (JRE)

  compile: javac XXXX.java

  run: java XXXX

  You can use Buildfiles and Ant command to simple the process.

Comments and embedded documentation

  There are two types of comments in Java.

    1) /*.....*/ multiline comment. (comes from C) Recommend writing:

      /* This is a comment

      * each line begin with a "*"

      */

    2) // single comment (comes from C++)

  Comment documentation

  Possibly the biggest problem with documenting code has been maintaining that documentation.

  If the documentation and the code are separate, it becomes tedious to change the documentation every time you change the code.

  The solution seems simple: Link the code to the documentation. The easiest way to do this is to put everything in the same file.

  To complete the picture, however, you need a special comment syntax to mark the documentation and a tool to extract those comments and put them in a useful form.

  The tool to extract the comments is called Javadoc. It uses some of the technology from the Java compiler to look for special comment tags that you put in your programs. It not only extracts the information marked by these tags, but it also pulls out the class name or method name that adjoins the comment.

  The output of Javadoc is an HTML file

  In addition, you can write your own Javadoc handlers, called doclets, if you want to perform special operations on the information processed by Javadoc.

  A thorough description can be found in the JDK documentation. When you unpack the documentation, look in the “tooldocs” subdirectory (or follow the “tooldocs” link).

  Syntax

  All of the Javadoc commands occur only within /** comments. The comments end with */ as usual. There are two primary ways to use Javadoc: Embed HTML or use “doc tags.”

  There are three “types” of comment documentation, which correspond to the element the comment precedes: class, field, or method. That is, a class comment appears right before the definition of a class, a field comment appears right in front of the definition of a field, and a method comment appears right in front of the definition of a method.  

  //: object/Documentation1.java

  /** A class comment */

  public class Documentation1 {

    /** A field comment */

    public int i;

    /** A method comment */

    public void f() {}

  } ///:~

  Note theat Javadoc will process comments documentation for only public and protected members. Comments for private and package-access members are ignored (You can use the -private flag to include private members as well.)

  Embedded HTML

  Javadoc passes HTML commands through to the generated HTML document. This allows you full use of HTML; however, the primary motive to let you format code. 

  //: object/Documentation2.java

  /**

  * <pre>

  * System.out.println(new Date());

  * </pre>

  */

  ///:~

  Note asterisks (*) at the beginning of a line are thrown away by Javadoc, along with leading spaces.

  Don't use headings such as <h1> or <hr> as embedded HTML, because Javadoc inserts its own headings and yours will interface with them.

  Some example tags

  @See

    This tag allows you to refer to the documentation in other classes.

    Javadoc will generate HTML with the @see tags hyperlinked to the other documentation

    @see classname

    @see fully-qualified-classname

    @see fully-qualified-classname#method-name

    Javadoc will not check the hyperlinks you give it to make sure they are valid.

  {@link package.class#member label}

    Very similar to @see,except that it can be used inline and uses the label as the hyperlink text rather than "See Also"

  {@docRoot}

    Produce the relative path to the documentation root directory.

  {@inheritDoc}

    Inherits the documentation from the nearest base class of the class into the current doc comment.

  @version

    form: @version version-information

    When the -version flag is placed on the Javadoc command line, the version information will be called out specially in the generated HTML documentation.

  @author

    form: @author author-information

    When the -author flag is placed on the Javadoc command line, the author information will be called out specially in the generated HTML documentation.

    You can have multiple author tags for a list of authors, but they must be placed consecutively.

  @since

    This tag allows you to indicate the version of this code that began using a particular feature.

  @param

    used for method docmentation

    form: @param parmeter-name description

    in which parameter-name is the identifier in the method parameter list, and description is text that can continue on subsequent lines. The description is considered finished when a new documentation tag is encountered. You can have any number of these, presumably one for each parameter.

  @return

    used for method documentation

    form: @reutrn description

    It can continue on subsequent lines.

  @throws

    used for method documentation

    form: @throws fully-qualified-class-name description

    description can continue on subsequent lines.

  @deprecated

    This is used to indicate features that were supperseded by an improved feature.

    The deprecated tag is a suggestion that you no longer use this particular feature,since sometime in the future it is likely to be removed.

    A method that is marked @deprecated causes the compiler to issue a warning if it is used.

    In Java SE5, the @deprecated Javadoc tag has been supperseded by the @Deprecated annotation

Coding style

  class: AllTheColorsOfTheRainbow

  for almost everything else-methods,fields,and object reference names:getColor(),color

  the placement of open-and-close curly braces

  The user must also type all these long names, so be merciful

  

  class AllTheColorsOfTheRainbow {

    int anIntegerRepresentingColors;

    void changeTheHueOfTheColor(int newHue) {

      // ...

    }

    // ...

  }

备注:Javadoc待需要的时候,深入学习