Friday, January 29, 2010

winconsi JAVA CLASSES

JAVA CLASSES


Contents


Fields, Methods, and Access Levels

  • Java classes contain fields and methods. A field is like a C++ data member, and a method is like a C++ member function.

  • Each field and method has an access level:
    • private: accessible only in this class
    • (package): accessible only in this package
    • protected: accessible only in this package and in all subclasses of this class
    • public: accessible everywhere this class is available
  • Similarly, each class has one of two possible access levels:
    • (package): class objects can only be declared and manipulated by code in this package
    • public: class objects can be declared and manipulated by code in any package
    Note: for both fields and classes, package access is the default, and is used when no access is specified.

    Simple Example Class

    Here's a (partial) example class; a List is an ordered collection of items of any type:

     class List {     // fields         private Object [] items;    // store the items in an array         private int       numItems; // the current # of items in the list          // methods         // constructor function         public List()         {             items = new Object[10]; 	    numItems = 0;         } 	 	// AddToEnd: add a given item to the end of the list 	public void AddToEnd(Object ob) 	{ ... } }  
    Notes
    • Object: Object-oriented programming involves inheritance. In Java, all classes (built-in or user-defined) are (implicitly) subclasses of Object. Using an array of Object in the List class allows any kind of Object (an instance of any class) to be stored in the list. However, primitive types (int, char, etc) cannot be stored in the list.

    • Constructor function: As in C++, constructor functions in Java:
      • Are used to initialize each instance of a class.
      • Have no return type (not even void).
      • Can be overloaded; you can have multiple constructor functions, each with different numbers and/or types of arguments.
      If you don't write any constructor functions, a default (no-argument) constructor (that doesn't do anything) will be supplied. If you write a constructor that takes one or more arguments, no default constructor will be supplied (so an attempt to create a new object without passing any arguments will cause a compile-time error).

      It is often useful to have one constructor call another (for example, a constructor with no arguments might call a constructor with one argument, passing a default value). The call must be the first statement in the constructor. It is performed using this as if it were the name of the method. For example:

        this( 10 );
      is a call to a constructor that expects one integer argument.

    • Initialization of fields: If you don't initialize a field (i.e., either you don't write any constructor function, or your constructor function just doesn't assign a value to that field), the field will be given a default value, depending on its type. The values are the same as those used to initialize newly created arrays (see the "Java vs C++" notes).

    • Access Control: Note that the access control must be specified for every field and every method; there is no grouping as in C++. For example, given these declarations:

        public
          int x;
          int y;

      only x is public; y gets the default, package access.

    Static Fields and Methods

  • Fields and methods can be declared static (this is true in C++, too). If a field is static, there is only one copy for the entire class, rather than one copy for each instance of the class. (In fact, there is a copy of the field even if there are no instances of the class.) For example, we could add the following field to the List class:
      static int numLists = 0; 
    And the following statement to the List constructor:
      numLists++; 
    Now every time a new List object is created, the numLists variable is incremented; so it maintains a count of the total number of Lists created during program execution. Every instance of a List could access this variable (could both read it and write into it), and they would all be accessing the same variable, not their own individual copies.

    A method should be made static when it does not access any of the non-static fields of the class, and does not call any non-static methods. (In fact, a static method cannot access non-static fields or call non-static methods.) Methods that would be "free" functions in C++ (i.e., not members of any class) should be static methods in Java. Also, methods that are logically associated with a particular class, but that only manipulate the class's static fields should be static. For example, if we wanted a function to print the current value of the numLists field defined above, that function should be defined as a static method of the List class.

    A public static field or method can be accessed from outside the class using either the usual notation:

        class-object.field-or-method-name   
    or using the class name instead of the name of the class object:
      class-name.field-or-method-name 
    For example, if the numLists field is public, and there is a variable L of type List, the numLists field can be accessed using either L.numLists or List.numLists. Similarly, if the List class includes a public static method PrintNumLists, then the method can be called using either L.PrintNumLists() or List.PrintNumLists().

    The preferred way to access a static field or a static method is using the class name (not using a class object). This is because it makes it clear that the field or method being accessed is static.

    Final Fields and Methods

  • Fields and methods can also be declared final. A final method cannot be overridden in a subclass. A final field is like a constant: once it has been given a value, it cannot be assigned to again. For example, the constructor function for the List class initializes the "items" field to (point to) an array of size 10. It would probably be better to use a constant for the initial size of the array. Only a single copy of the constant is needed for the whole class, not one for every class instance, so it would be appropriate to make the field static as well as final:
      private static final int INITIAL_SIZE = 10; 
    The assignment statement in the constructor function would change to:
      items = new Object[INITIAL_SIZE]; 

    TEST YOURSELF #1

    Consider the program defined below.

      class Test {   static int x;   int k;      // constructor with 2 args   public Test( int n, int m ) {     x = n;     k = m;   }      public static void main(String[] args) {     Test t1 = new Test(10, 20);     Test t2 = new Test(30, 40);     System.out.print(t1.x + " ");     System.out.print(t1.k + " ");     System.out.print(t2.x + " ");     System.out.println(t2.k);   } } 
    Question 1: Which of the following is true?
      A. This program must be in a file called Test.java.  Compiling will create one    new file called Test.class. B. This program can be in any .java file.  Compiling will create one new file    called Test.class. C. This program must be in a file called Test.java.  Compiling will create two    new files called Test.class and main.class. D. This program can be in any .java file.  Compiling will create two new files    called Test.class and main.class. 

    Question 2: Which of the following correctly describes what happens when the program is compiled and run?

      A. There will be a compile-time error because there is no constructor with no    arguments. B. There will be a run-time error because there is no constructor with no    arguments. C. There will be no errors; the output will be: 10 20 30 40 D. There will be no errors; the output will be: 30 20 30 40 E. There will be no errors; the output will be: 30 40 30 40 

    solution


    Some Useful Built-in Classes

    Note: These classes are not really part of the language; they are provided in the package java.lang. You can get more information on-line via the Java Packages page.

    String

    • to create a String:
          String S1 = "hello",              // initialize from a string literal            S2 = new String("bye"),    // use new and the String constructor 	   S3 = new String(S1);       // use new and a different constructor      
      There are lots more String constructors, see the documentation.

    • to concatenate:
            String S1 = "hello" + "bye",              S2 = S1 + "!", 	     S3 = S1 + 10;          // the int 10 will be converted to a String, 	                            // because the other operand of + is a 				    // String     
      Note: in all of the examples above, a new string is created and the variable (S1, S2, or S3) is set to point to that new string. For example, the expression S1 + "!" does not change what S1 points to, it creates a new string that contains "hellobye!".

    • Other methods of the String class:
            int length()          // Note: different from arrays, which just use                             //       length without parens       char charAt(int k)    // return the kth character in the string, starting                             // with 0                             // runtime error if k <>= length()       int compareTo(String S) // compare this string with string S                               // return: 			      //   0 if they are the same 	                      //   a positive int if this string is greater 		              //   a negative int if this string is less       boolean equals(Object S) // return true if S is a non-null String that                                // contains the same characters as this String       String substring( -- several forms -- )  // see documentation       toLowerCase()       toUpperCase()       Lots more -- see documentation!     

    Object

    • this is the base class for all Java classes.

    • methods:
            String toString()  // return a string representation of this object                          // note: for user-defined classes, the default value 			 //       is not very useful so you should define your 			 //       own toString method       boolean equals(Object ob)  // return true iff this object is the same as                                  // ob                                  // note: uses pointer equality for user- 				 //       defined classes; you may want to 				 //       redefine this method       More -- see documentation!     

    Boolean, Integer, Double, etc

    • One such class for each primitive type.

    • Use these "wrapper" classes when you need an Object. For example, think about the List class. Suppose you try this:
               List L = new List(); 	 L.AddToEnd( 10 );        
      You get a compile-time error saying that type int cannot be converted to type Object. That's because the AddToEnd method takes an Object as its parameter, and a primitive type like int is not an Object. You can fix this using:
               L.AddToEnd( new Integer( 10 ) );        
      This creates a new Integer object, with the value 10, and passes that object to the AddToEnd method. Note that if you want to retrieve a particular kind of object from a list, you must use a cast. For example, assume that the List class also includes methods to allow a user of the class to iterate through the items in a list; i.e., we think of every list as having a "current pointer", and methods are provided to get the current item, and to move the current pointer:
             public void firstElement()  // set the current pointer to point to the                                    // first item on the list        public Object NextElement() // return the item pointed to by the current                                    // pointer; also advance the current pointer        public boolean hasMoreElements()  // true iff the current pointer has                                          // not fallen off the end of the list        
      If you do this:
               L.AddToEnd( new Integer( 10 ) );          L.firstElement(); 	 Integer K = L.nextElement();        
      you'll get a compile-time error saying that you must use an explicit cast to convert an Object to an Integer. That's because the return type of nextElement is Object, and you're trying to assign that into variable K, which is an Integer. Here's what you need to do:
               Integer K = (Integer)L.nextElement();        

    • You can get back a (primitive) value from these wrapper classes using the method xxxValue, where xxx is the primitive type. For example:
               Integer K = new Integer( 10 ); 	 int     x = K.intValue(); 	 Boolean B = new Boolean( true ); 	 boolean b = B.boolValue();        

    • These classes also provide some useful constants: Integer.MAX_VALUE (the largest int that can be represented), Integer.MIN_VALUE, Double.MAX_VALUE, Double.MIN_VALUE, Double.POSITIVE_INFINITY, etc.

    TEST YOURSELF #2

    Question 1: Consider the following program.

      class Test {     static void Swap(Integer j, Integer k) {         int tmp = k.intValue();         k = new Integer(j.intValue());         j = new Integer(tmp);     }          public static void main(String[] args) {         Integer n = new Integer(5), m = new Integer(6);         Swap(n, m);         System.out.println("n = " + n + "; m = " + m);     } } 
    The person who wrote this program expected the output to be: n = 6; m = 5. However, the actual output is: n = 5; m = 6. Explain why.

    Question 2: Consider the following function. This function was intended to create and return a string that is the reverse of its parameter. (For example, if parameter S = "hello", the function should return "olleh".) However, there are several problems with the function as written.

      static String Reverse(String S) {     String newS = "";     char c = S[0];     while (c) {         newS = c + newS;         c++;     }     return newS; } 
    First, identify each problem (write the bad code and give a brief explanation of why it is incorrect). Then give a new, correct version of function Reverse.

    solution


    Solutions to Self-Study Questions

    Test Yourself #1

      Question 1:   B. This program can be in any .java file.  Compiling will create one new file    called Test.class.  (It does not have to be in Test.java, because class    Test is not public.  No file "main.class" is created, because main is a    method, not a class.)  Question 2:   D. There will be no errors; the output will be: 30 20 30 40    (There is no need for a constructor with no arguments because there    are no uses of "new Test" with no arguments.) 

    Test Yourself #2

      Question 1: Why does this program produce the output n = 5; m = 6?  In Java, all parameters are passed by value, so changes to the parameters themselves in the function do not affect the values that were passed. The Swap function changes its parameters, j and k, making them point to new Integers, but that has no effect on the values that were passed (variables n and m).   Question 2:         static String Reverse(String S) {            String newS = "";            char c = S[0];	// can't index Strings in Java            while (c) {		// not a boolean loop condition  				//   (but this would work in C/C++)                newS = c + newS;                c++;		// this doesn't help fetch the next char in S 				//   (increments ascii value of c)            }            return newS;        }  Correct version:  	static String Reverse(String S) { 	   String newS = ""; 	   for (int i=0; i
  • JAVA vs C++

    JAVA vs C++


    http://pages.cs.wisc.edu/~hasti/cs368/JavaTutorial/

    Contents


    In Java, every variable, constant, and function (including main) must be inside some class. Here's a simple example program:
     	class Test { 		public static void main( String [] args ) 		{ 		    System.out.println("Hello world!"); 		} 	}  
    Things to note:
    1. There is no final semi-colon at the end of the class definition.

    2. Function main is a member of class Test.

    3. In general, main must:
      • Be inside some class (there can be more than one main function -- there can even be one in every class!)
      • Be public static void.
      • Have one argument: an array of String. This array contains the command-line arguments. You can use args.length to determine the number of arguments (the number of Strings in the array).

    4. To write to standard output, you can use either of the following:
      	System.out.println( ... ) 	System.out.print( ... )     
      The former prints the given expression followed by a newline, while the latter just prints the given expression.

      Like the C++ <<>

      	System.out.print("hello");   // print a String 	System.out.print(16);        // print an integer 	System.out.print(5.5 * .2);  // print a floating-point number        

      The + operator can be useful when printing. It is overloaded to work on Strings as follows:

      If either operand is a String, it

      1. converts the other operand to a String (if necessary)
      2. creates a new String by concatenating both operands

      Example

      	int x = 20, y = 10; 	System.out.println("x: " + x + "\ny: " + y);        
      The output is:
             x: 20        y: 10        
      This is because the argument to println is an expression of the form:
        op1 + op2 + op3 + op4

      The only operator is +, so the expression is evaluated left-to-right (if there were another operator with higher precedence, the sub-expression involving that operator would be evaluated first). The leftmost sub-expression is:

        "x: " + x
      One operand (the left one) is a String, so the other operand is converted from an int to a String, and the two strings are concatenated, producing the value:
        "x: 20"

      Evaluation of the argument to println continues, producing as the final value the String shown above (note that \n means the newline character):

      	x: 20  	y: 10        

    TEST YOURSELF #1

    Assume the following declarations have been made:

        int x = 20, y = 10; 
    What is printed when each of the following statements is executed?
        System.out.println(x + y);     System.out.println(x + y + "!");     System.out.println("printing: " + x + y);     System.out.println("printing: " + x * y); 

    solution


    C++ Files vs Java Files

    A C++ programmer deals with source files, object files, and executable files:

    Source Files: .h and .cc (or .cpp or .C)

      created by:  you (the programmer)   contain   :  C++ source code   two kinds :         .h (header files) 	       contain class definitions and function specifications                        (just headers - no bodies)                must be included by every file that uses the class / calls the 	               functions         .cc contain implementations of class member functions and "free" functions, 	            including the main function 	

    Object Files: .o

      created by:  the compiler, when called w/ -c flag; for example: 			g++ -c main.cc 	       compiles main.cc creating main.o   contain   :  object code (not executable)                source code is compiled, but not linked/loaded   

    Executable Files

      created by:  the compiler (no -c flag)   contain   :  executable code 	 	      Code is compiled if necessary, then linked and loaded. 		      These are the files that you can actually run, just by typing 		      the name of the file.   name      :  default = a.out                any other name is possible via the -o flag; for example: 			g++ main.o -o test  	       creates an executable named "test"   

    A Java programmer deals with source files and bytecode files (no executable files):

    Source Files: .java

      created by   :  you (the programmer)   contain      :  Java source code (one or more classes per file)   restrictions :      (1) each source file can contain at most one public class      (2) if there is a public class, then the class name and file name must match            Examples      	If a source file contains the following: 		public class Test { ... } 		class Foo { ... } 		class Bar {... } 	then it must be in a file named Test.java 	 	If a source file contains the following: 		class Test { ... } 		class Foo { ... } 		class Bar {... } 	then it can be in any ".java" file 	
    Small digression:
    • Every function must be part of a class.
    • Every class is part of a package (packages are discussed in a later set of notes.).
    • A public class can be used in any package.
    • A non-public class can only be used in its own package.
    End of digression.

    Bytecode Files: .class

      created by:  the Java compiler   contain   :  Java bytecodes, ready to be "executed" -- really interpreted -- by                                the Java interpreter   names     :  for each class in a source file (both public and non-public classes),                the compiler creates one ".class" file, where the file name is the 	       same as the class name    Example      If a source file contains the following: 	public class Test { ... } 	class Foo { ... } 	class Bar {... }      then after compiling you will have three files:      	Test.class 	Foo.class 	Bar.class                  

    Here's how to compile and run the example "hello world" program given above, assuming that it is in a file named "tst.java":

    1. to compile the source code, type: javac tst.java

    2. to run the interpreter using the name of the class whose main function you want to run, type: java Test

    Remember, when compiling a program, you type the full file name, including the ".java" extension; when running a program, you just type the name of the class whose main function you want to run.


    TEST YOURSELF #2

    Write a complete Java program that uses a loop to sum the numbers from 1 to 10 and prints the result like this:

        The sum is: xxx 
    Note: Use variable declarations, and a for or while loop with the same syntax as in C++.

    Make sure that you are able to compile and execute your program!

    solution


    Java Types

    In Java, there are two "categories" of types: primitive types and reference types:

        Primitive Types
      booleansame as bool in C++
      charholds one character
      byte8-bit signed integer
      short16-bit signed integer
      int32-bit signed integer
      long64-bit signed integer
      floatfloating-point number
      doubledouble precision floating-point number
        Reference Types
        arrays
        classes

    Notes:

    1. no struct, union, enum, unsigned, typedef
    2. arrays and classes are really pointers!!

    C++ Arrays vs Java Arrays

    • In C++, when you declare an array, storage for the array is allocated. In Java, when you declare an array, you are really only declaring a pointer to an array; storage for the array itself is not allocated until you use "new":
                   C++                                int A[10];  // A is an array of length 10	     A[0] = 5;   // set the 1st element of array A                                                 JAVA  int [] A;          // A is a pointer to an array A = new int [10];  // now A points to an array of length 10 A[0] = 5;          // set the 1st element of the array pointed to by A 
    • In both C++ and Java you can initialize an array using values in curly braces. Here's example Java code:
        int [] A = {1, 222, 0};  // A points to an array of length 3                          // containing the values 1, 222, and 0 
    • In Java, a default initial value is assigned to each element of a newly allocated array if no initial value is specified. The default value depends on the type of the array element:
      TypeValue
      booleanfalse
      char'\u0000'
      byte, int, short, int, long, float, double0
      any pointernull

    • In Java, an out-of-bounds array index always causes a runtime error.

    • In Java, you can determine the current length of an array (at runtime) using ".length":
        int [] A = new int[10];     ...  A.length ...        // this expression evaluates to 10     A = new int[20];     ...  A.length ...        // now it evaluates to 20 

    TEST YOURSELF #3

    Write a Java function called NonZeros, using the header given below. NonZeros should create and return an array of integers containing all of the non-zero values in its parameter A, in the same order that they occur in A.

        public static int[] NonZeros( int [] A ) 

    Write a complete Java program that includes a main function as well as the NonZeros function. The main function should test NonZeros by creating several arrays, and calling NonZeros with each array. It should print the array it passes to NonZeros as well as the returned array. So for example, when you run your program, your output might look like this (if your NonZeros function is implemented correctly):

        passing [0,1,2,3,2] got back [1,2,3,2]     passing [0,0] got back []     passing [22,0,-5,0,126] got back [22,-5,126]     passing [1,0] got back [1] 

    solution



    TEST YOURSELF #4

    For each of the following code fragments, fill in the number of the picture that best illustrates the value of A after the code executes, or fill in "error" to indicate that executing the code causes a runtime error. (In the pictures, a diagonal line indicates a null pointer.)

    CodeCorresponding Picture or Error
    int [] A;
    int [] A = new int [4];
    int [][] A = new int[4][3];
    int [][] A = new int[4][];
    A[1] = new int[4];
    A[3] = new int[2];
    int [] A = new int[4];
    int [] B = {0,1,2,3,4,5,6,7,8,9};
    System.arraycopy(B,2,A,0,4);
    int [] A = new int[4];
    int [] B = {2,3,4};
    System.arraycopy(B,0,A,0,4);
    int [] A = new int[4];
    int [] B = {0,1,2,3,4,5,6,7,8,9};
    System.arraycopy(B,8,A,0,4);
    int [] A = {1,1,1,1};
    int [] B = {2,2,2};
    System.arraycopy(A,0,B,1,2);
    System.arraycopy(B,0,A,0,3);
    int [] A = new int[4];
    int [] B = {0,1,2,3,4,5,6,7,8,9};
    System.arraycopy(B,0,A,0,10);
    int [][] A = new int[4][3];
    int [] B = {1,2,3,4,5,6,7,8,9,10};
    System.arraycopy(B,0,A[0],0,3);
    System.arraycopy(B,1,A[1],0,3);
    System.arraycopy(B,2,A[2],0,3);
    System.arraycopy(B,3,A[3],0,3);

    PICTURES

    (1)(2)(3)

    (4)(5)(6)

    (7)(8)(9)

    (10)(11)(12)
    (13)(14)(15)

    solution


    C++ Classes vs Java Classes

    • In C++, when you declare a variable whose type is a class, storage is allocated for an object of that class, and the class's constructor function is called to initialize that instance of the class. In Java, you are really declaring a pointer to a class object; no storage is allocated for the class object, and no constructor function is called until you use "new". Assume that you have defined a List class as follows:
        class List {   public void AddToEnd(...)   { ...}   ... } 
                   C++  List L;          // L is a List; the List constructor function is called to                  // initialize L. List *p;         // p is a pointer to a List;                  // no list object exists yet, no constructor function has 		 // been called p = new List;    // now storage for a List has been allocated                  // and the constructor function has been called L.AddToEnd(...)  // call L's AddToEnd function p->AddToEnd(...) // call the AddToEnd function of the List pointed to by p                                                  JAVA  List L;         // L is a pointer to a List; no List object exists yet L = new List(); // now storage for a List has been allocated                 // and the constructor function has been called; 		// note that you must use parentheses even when you are not 		// passing any arguments to the constructor function L.AddToEnd(...) // no -> operator in Java -- just use . 

    Aliasing Problems in Java

    The fact that arrays and classes are really pointers in Java can lead to some problems:

    Problem 1: Simple assignment causes aliasing:

    Java code                          conceptual picture                                           (all empty boxes contain zeros)                                        +--+       +---+---+---+ int [] A = new int[3],             A: | -|-----> |   |   |   |                                       +--+       +---+---+---+         B = new int[2];                +--+       +---+---+                                    B: | -|-----> |   |   |                                       +--+       +---+---+                                        +--+       +---+---+---+        A[0] = 5;                   A: | -|-----> | 5 |   |   |                                       +--+       +---+---+---+                                        +--+       +---+---+---+        B = A;                      A: | -|-----> | 5 |   |   |                                       +--+       +---+---+---+ 				                 ^ 				      +--+       | 				   B: | -|-------+ 				      +--+                                        +--+       +---+---+---+ *** NOTE **         B[0] = 2;                  A: | -|-----> | 2 |   |   | the value of A[0]                                       +--+       +---+---+---+ changed, too! 				                 ^ 				      +--+       | 				   B: | -|-------+ 				      +--+  

    Problem 2: In Java, all parameters are passed by value, but for arrays and classes the actual parameter is really a pointer, so changing

    • an array element, or
    • a class field
    inside the function does change the actual parameter's element or field. For example:
    void f( int [] A ) {     A[0] = 10;   // change an element of parameter A     A = null;    // change A itself }  void g() {     int [] B = new int [3];     B[0] = 5;     f(B);     *** B is not null here, because B itself was passed by value     *** however, B[0] is now 10, because function f changed the first element     *** of the array }  
    In C++, similar problems can arise when a class that has pointer data members is passed by value. This problem is addressed by the use of copy constructors, which can be defined to make copies of the values pointed to, rather than just making copies of the pointers. In Java, the solution is to use the arraycopy operation, or to use a class's clone operation. Cloning will be discussed later.
    TEST YOURSELF #5

    For each of the following Java code fragments, say whether it causes a compile-time error, a run-time error, or no error. If there is an error, explain why.

       1. int A[5];     2. int [] A, B;       B = 0;     3. int [] A = {1,2,3};       int [] B;       B = A;     4. int [] A;       A[0] = 0;     5. int [] A = new int[20];       int [] B = new int[10];       A = B;       A[15] = 0; 

    solution


    Type Conversion

    Java is much more limited than C++ in the type conversions that are allowed. Here we discuss conversions among primitive types. Conversions among class objects will be discussed later.

    Booleans cannot be converted to other types. For the other primitive types (char, byte, short, int, long, float, and double), there are two kinds of conversion: implicit and explicit.

    Implicit conversions: An implicit conversion means that a value of one type is changed to a value of another type without any special directive from the programmer. A char can be implicitly converted to an int, a long, a float, or a double. For example, the following will compile without error:

      char c = 'a'; int k = c; long x = c; float y = c; double d = c; 
    For the other (numeric) primitive types, the basic rule is that implicit conversions can be done from one type to another if the range of values of the first type is a subset of the range of values of the second type. For example, a byte can be converted to a short, int, long or float; a short can be converted to an int, long, float, or double, etc.

    Explicit conversions: Explicit conversions are done via casting: the name of the type to which you want a value converted is given, in parentheses, in front of the value. For example, the following code uses casts to convert a value of type double to a value of type int, and to convert a value of type double to a value of type short:

      double d = 5.6; int k = (int)d; short s = (short)(d * 2.0); 
    Casting can be used to convert among any of the primitive types except boolean. Note, however, that casting can lose information; for example, floating-point values are truncated when they are cast to integers (e.g., the value of k in the code fragment given above is 5), and casting among integer types can produce wildly different values (because upper bits, possibly including the sign bit, are lost). So use explicit casting carefully!
    TEST YOURSELF #6

    Fill in the table below as follows:

    • If the declaration will compile as is, put a check in the second column, and write the value of the declared variable in the last column.
    • If the declaration will not compile as is, but can be made to compile by adding an explicit cast, rewrite the declaration with the correct explicit cast in the third column, and write the value of the declared variable in the last column.
    • If the declaration will not compile, and cannot be fixed by adding an explicit cast, put a check in the fourth column.
    The first row has been filled in as an example.

    DeclarationCorrectRewrite with castNever correctVariable's value
    double d = 5;X5.0
    int k = 5.6;
    long x = 5.4;
    short n = 99999;
    int b = true;
    char c = 97;
    short s = -10.0;

    solution


    Solutions to Self-Study Questions

    Test Yourself #1

      System.out.println(x + y);                  ==>     30 System.out.println(x + y+ "!");             ==>     30! System.out.println("printing: " + x + y);   ==>     printing: 2010 System.out.println("printing: " + x * y);   ==>     printing: 200 

    Test Yourself #2

      class Test {   public static void main( String[] args ) {     int sum = 0;     for (int k=1; k<=10; k++) sum += k;     System.out.println("The sum is: " + sum);   } } 

    Test Yourself #3

      class Test {   public static int[] NonZeros( int[] A ) {     // count # nonzero values       int nonz = 0;       for (int k=0; k

    Test Yourself #4

              CODE                    CORRESPONDING PICTURE         ----                    ---------------------     int [] A;                           9      int [] A = new int[4];              6      int [][] A = new int[4][3];         3      int [][] A = new int[4][];     A[1] = new int[4];     A[3] = new int[2];                  1      int [] A = new int[4];     int [] B = {0,1,2,3,4,5,6,7,8,9};     System.arraycopy(B,2,A,0,4);        14      int [] A = new int[4];     int [] B = {2,3,4};     System.arraycopy(B,0,A,0,4);        error      int [] A = new int[4];     int [] B = {0,1,2,3,4,5,6,7,8,9};     System.arraycopy(B,8,A,0,4);        error      int [] A = {1,1,1,1};     int [] B = {2,2,2};     System.arraycopy(A,0,B,1,2);     System.arraycopy(B,0,A,0,3);        12      int [] A = new int[4];     int [] B = {0,1,2,3,4,5,6,7,8,9};     System.arraycopy(B,0,A,0,10);       error      int [][] A = new int[4][3];     int [] B = {1,2,3,4,5,6,7,8,9,10};     System.arraycopy(B,0,A[0],0,3);     System.arraycopy(B,1,A[1],0,3);     System.arraycopy(B,2,A[2],0,3);     System.arraycopy(B,3,A[3],0,3);     10 

    Test Yourself #5

          int A[5];         Compile-time error: Can't specify array dimension in a declaration.         This is C/C++ syntax.      int [] A, B;     B = 0;         Compile-time error: Incompatible type for =. Can't convert int to         int[].  B is an array reference, not an int, and 0 is not equiv to         null as in C/C++.      int [] A = {1,2,3};     int [] B;     B = A;         No errors.      int [] A;     A[0] = 0;         Compile-time error: Variable A may not have been initialized.         The array was never allocated.      int [] A = new int[20];     int [] B = new int[10];     A = B;     A[15] = 0;         Runtime error: ArrayIndexOutOfBoundsException: 15         A now references the same array as B, which only has length 10 

    Test Yourself #6

      Declaration     Correct   Rewrite with cast   Never correct   Variable's value  ------------------------------------------------------------------------------ double d = 5;      X                                              5.0 int k = 5.6;              int k = (int) 5.6                       5 long x = 5.4;            long x = (long) 5.4                      5 short n = 99999;        short n = (short) 99999                   -31073 int b = true;                                      X char c = 97;       X                                              'a'  short s = -10.0;        short s = (short) -10.0                   -10