Java Enterprise Java Java Advanced Placement Study Guide: Logical Operations, Numeric Cast, String Concatenation, and...

Java Advanced Placement Study Guide: Logical Operations, Numeric Cast, String Concatenation, and the toString() Method

Questions


File JavaAP008.htm


Welcome


This is one in a miniseries of tutorial lessons designed to help you learn
the essential features of Java object-oriented programming as identified
by The College Board.

Purpose

The purpose of this miniseries is to help you study for, and successfully
complete, the Advanced Placement Examinations designed by the College Board.

Once you understand everything in this miniseries, plus the material
in the lessons that I published earlier on Java
Data Structures
, you should understand the Java programming features
that the College Board considers essential for the first two semesters
of object-oriented programming education at the university level.

Hopefully, that will help you to take and successfully complete the
Advanced Placement Examinations.

Approach

These lessons provide questions, answers, and explanations designed
to help you to understand the subset
of Java features covered by the Java Advanced Placement Examinations (as
of October, 2001).

Please see the first lesson in the miniseries entitled Java
Advanced Placement Study Guide: Introduction to the Lessons, Primitive
Types
, for additional background information.  The lesson immediately
prior to this one was entitled Java Advanced Placement
Study Guide:  Relational Operators, Increment Operator, and Control
Structures
.

Supplementary material

In addition to the material in these lessons, I recommend that you also
study the other lessons in my extensive collection of online Java tutorials,
which are designed from a more conventional textbook approach.  You
will find those lessons published at
Gamelan.com
However, as of the date of this writing, Gamelan doesn’t maintain a consolidated
index of my Java tutorial lessons, and sometimes they are difficult to
locate there.  You will find a consolidated index at
Baldwin’s
Java Programming Tutorials
.

What is Included?

Click here for a preview of the Java
programming features covered by this lesson.



1.  What output is produced by the following
program?

  • A.  Compiler Error
  • B.  Runtime Error
  • C.  A
  • D.  B
  • E.  None of the above
public class Ap039{
  public static void main(
                        String args[]){
    new Worker().doLogical();
  }//end main()
}//end class definition

class Worker{
  public void doLogical(){
    int x = 5, y = 6;
    if((x > y) || (y < x/0)){
      System.out.println("A");
    }else{
      System.out.println("B");
    }//end else
  }//end doLogical()
}//end class definition

Answer and Explanation

2.  What output is produced by the following program?

  • A.  Compiler Error
  • B.  Runtime Error
  • C.  A
  • D.  B
  • E.  None of the above
public class Ap040{
  public static void main(
                        String args[]){
    new Worker().doLogical();
  }//end main()
}//end class definition

class Worker{
  public void doLogical(){
    int x = 5, y = 6;
    if((x < y) || (y < x/0)){
      System.out.println("A");
    }else{
      System.out.println("B");
    }//end else
  }//end doLogical()
}//end class definition

Answer and Explanation

3.  What output is produced by the following program?

  • A.  Compiler Error
  • B.  Runtime Error
  • C.  A
  • D.  B
  • E.  None of the above
public class Ap041{
  public static void main(
                        String args[]){
    new Worker().doLogical();
  }//end main()
}//end class definition

class Worker{
  public void doLogical(){
    int x = 5, y = 6;
    if(!(x < y) && !(y < x/0)){
      System.out.println("A");
    }else{
      System.out.println("B");
    }//end else
  }//end doLogical()
}//end class definition

Answer and Explanation

4.  What output is produced by the following program?

  • A.  Compiler Error
  • B.  Runtime Error
  • C.  true
  • D.  1
  • E.  None of the above
public class Ap042{
  public static void main(
                        String args[]){
    new Worker().doCast();
  }//end main()
}//end class definition

class Worker{
  public void doCast(){
    boolean x = true;
    int y = (int)x;
    System.out.println(y);
  }//end doCast()
}//end class definition

Answer and Explanation

5.  What output is produced by the following program?

  • A.  Compiler Error
  • B.  Runtime Error
  • C.  4 -4
  • D.  3 -3
  • E.  None of the above
public class Ap043{
  public static void main(
                        String args[]){
    new Worker().doCast();
  }//end main()
}//end class definition

class Worker{
  public void doCast(){
    double w = 3.7;
    double x = -3.7;
    int y = (int)w;
    int z = (int)x;
    System.out.println(y + " " + z);
  }//end doCast()
}//end class definition

Answer and Explanation

6.  What output is produced by the following program?

  • A.  Compiler Error
  • B.  Runtime Error
  • C.  4 -3
  • D.  3 -4
  • E.  None of the above
public class Ap044{
  public static void main(
                        String args[]){
    new Worker().doCast();
  }//end main()
}//end class definition

class Worker{
  public void doCast(){
    double w = 3.5;
    double x = -3.499999999999;

    System.out.println(doIt(w) + 
                       " " +
                       doIt(x));
  }//end doCast()
    
  private int doIt(double arg){
    if(arg > 0){
      return (int)(arg + 0.5);
    }else{
      return (int)(arg - 0.5);
    }//end else
  }//end doIt()
}//end class definition

Answer and Explanation

7.  What output is produced by the following program?

  • A.  Compiler Error
  • B.  Runtime Error
  • C.  3.5/9/true
  • D.  None of the above
public class Ap045{
  public static void main(
                        String args[]){
    new Worker().doConcat();
  }//end main()
}//end class definition

class Worker{
  public void doConcat(){
    double w = 3.5;
    int x = 9;
    boolean y = true;
    String z = w + "/" + x + "/" + y;
    System.out.println(z);
  }//end doConcat()
}// end class

Answer and Explanation

8.  Which of the following best approximates the
output from this program?

public class Ap046{
  public static void main(
                        String args[]){
    new Worker().doConcat();
  }//end main()
}//end class definition

class Worker{
  public void doConcat(){
    Dummy y = new Dummy();
    System.out.println(y);
  }//end doConcat()
}// end class

class Dummy{
  private String name = "Joe";
  private int age = 35;
  private double weight = 162.5; 
}//end class dummy

Answer and Explanation

9.  Which of the following best approximates the
output from this program?

  • A.  Compiler Error
  • B.  Runtime Error
  • C.  C.  [email protected]
  • D.  Joe  Age = 35  Weight = 162.5
public class Ap047{
  public static void main(
                        String args[]){
    new Worker().doConcat();
  }//end main()
}//end class definition

class Worker{
  public void doConcat(){
    Dummy y = new Dummy();
    System.out.println(y);
  }//end doConcat()
}// end class

class Dummy{
  private String name = "Joe";
  private int age = 35;
  private double weight = 162.5;
  
  public String toString(){
    String x = name + " " +
               " Age = " + age + " " +
               " Weight = " + weight;
    return x;
  } 
}//end class dummy

Answer and Explanation

10.  Which of the following best approximates
the output from this program when it is executed sometime during the year
2001?  (Note the use of the constructor for the Date class that
takes no parameters.)

  • A.  Compiler Error
  • B.  Runtime Error
  • C.  Tue Feb 06 09:56:09 CST 2001
  •       981474969593
  • D.  Thur Jan 01 00:00:00 GMT 1970
  •       0
  • None of the above
import java.util.*;
public class Ap048{
  public static void main(
                        String args[]){
    new Worker().doConcat();
  }//end main()
}//end class definition

class Worker{
  public void doConcat(){
    Date w = new Date();
    String y = w.toString();
    System.out.println(y);
    System.out.println(w.getTime());
  }//end doConcat()
}// end class

Answer and Explanation



Copyright 2002, Richard G. Baldwin.  Reproduction in whole or
in part in any form or medium without express written permission from Richard
Baldwin is prohibited.

About the author

Richard Baldwin
is a college professor (at Austin Community College in Austin, TX) and
private consultant whose primary focus is a combination of Java and XML.
In addition to the many platform-independent benefits of Java applications,
he believes that a combination of Java and XML will become the primary
driving force in the delivery of structured information on the Web.

Richard has participated in numerous consulting projects involving
Java, XML, or a combination of the two.  He frequently provides onsite
Java and/or XML training at the high-tech companies located in and around
Austin, Texas.  He is the author of Baldwin’s Java Programming Tutorials,
which has gained a worldwide following among experienced and aspiring Java
programmers. He has also published articles on Java Programming in Java
Pro magazine.

Richard holds an MSEE degree from Southern Methodist University and
has many years of experience in the application of computer technology
to real-world problems.

[email protected]


What is Included?


According to the subset
document,

  • “Logical operations &&, ||, ! are part of the AP
    CS subset. Students need to understand the “short circuit” evaluation of
    the && and || operators.”
  • “The numeric cast (int) is part of the AP CS subset. 
    Since the only tested fundamental types are int, double
    and boolean, the only required numeric cast is the cast
    (int).
    Students are expected to understand its “truncation towards 0” behavior
    as well as the fact that positive floating-point numbers can be rounded
    to the nearest integer as (int)(x+0.5), negative numbers
    as (int)(x-0.5)"
  • “String concatenation + is part of the AP CS subset.. Students
    are expected to know that concatenation converts numbers to strings and
    invokes toString on objects.”

Answers and Explanations

Answer 10


C.  Tue Feb 06 09:56:09 CST 2001

      981474969593

Back to Question 10

Explanation 10


The noarg constructor for the Date class

The Date class has a constructor that takes
no parameters and is described in the documentation as follows:

“Allocates a Date object and initializes
it so that it represents the time at which it was allocated, measured to
the nearest millisecond.”

In other words, this constructor can be used to instantiate
a Date object that represents the current date and time according
to the system clock.

A property named time of type long

The actual date and time information encapsulated
in a Date object is apparently stored in a property named time
as a long integer.

(The AP CS test doesn’t test for long
integers, but this is one situation where you will need to know that they
exist, and that they have the ability to store a very wide range of values.)

Milliseconds since the epoch

The long integer encapsulated in a Date
object represents the total number of milliseconds for the encapsulated
date and time, relative to the epoch, which was
Jan 01 00:00:00
GMT 1970.

Earlier dates are represented as negative values.  Later dates
are represented as positive values.

An overridden toString method

An object of the Date class has an overridden toString()
method that converts the value in milliseconds to a form that is more useful
for a human observer, such as:

Tue Feb 06 09:56:09 CST 2001

Instantiate a Date object with the noarg constructor

This program instantiates an object of the Date class using the
constructor that takes no parameters.

Invoke the overridden toString method

Then it invokes the overridden
toString() method to populate
a String object that represents the Date object.

Following this, it displays that String object, producing the
output  shown above.  (The actual date and time will vary
depending on when the program is executed.)

Get the time property value

Then it invokes the getTime() method to get and display the value
of the time property.

This is a representation of the same date and time shown above, but
in milliseconds:

981474969593

 

Answer 9


D.  Joe  Age = 35  Weight = 162.5

Back to Question 9

Explanation 9


Upgraded program from Question 8

The program used for this Question is an upgrade to the program that
was used for Question 8.

Dummy class overrides the toString method

In particular, in this program, the class named
Dummy overrides
the toString() method in such a way as to return a String
representing the object that would be useful to a human observer.

The String that is returned contains the values of the instance
variables of the object:  name, age, and weight.

Overridden toString method code

The overridden toString() method for the Dummy class is
shown below for easy reference.

 

  public String toString(){
    String x = name + " " +
               " Age = " + age + " " +
               " Weight = " + weight;
    return x;
  }//end toString() 

The code in the overridden toString() method is almost trivial.

The important thing is not the specific code in a specific overridden
version of the toString() method.

Why override the toString method?

Rather, the important thing is to understand why you should probably
override the toString() method in most new classes that you define.

In fact, you should probably override the toString() method in
all new classes that you define if a String representation of an
instance of that class will ever be needed.

The code will vary

The code required to override the toString() method will vary
from one class to another.  The important point is that the code must
return a reference to a String object.  The String object
should encapsulate information that represents the original object in a
format that is meaningful to a human observer.

Answer 8


C.  [email protected]

Back to Question 8

Explanation 8


Display an object of the Dummy class

This program instantiates a new object of the
Dummy
class, and passes that object’s reference to the method named println().

The purpose of the println() method is
to display a representation of the new object that is meaningful to a human
observer.  In order to do so, it requires a String representation
of the object.

The toString method

The class named Object defines a default
version of a method named toString().

All classes inherit the toString() method.

A child of the Object class

Those classes that extend directly from the class
named Object inherit the default version of the toString()
method.

Grandchildren of the Object class

Those classes that don’t directly extend the class
named Object also inherit a version of the toString() method.

May be default or overridden version

The inherited toString method may be the
default version, or it may be an overridden version, depending on whether
the method has been overridden in a superclass of the new class.

The purpose of the toString() method

The purpose of the toString() method defined
in the Object class is to be overridden in new classes.

The body of the overridden version should return
a reference to a String object, which represents an object of the
new class.

Whenever a String representation of an object
is required

Whenever a String representation of an
object is required for any purpose in Java, the toString() method
is invoked on a reference to the object.

The String that is returned by the toString()
method is taken to be a String that represents the object.

When toString has not been overridden

When the toString() method is invoked on
a reference to an object for which the method has not been overridden,
the default version of the method is invoked.

The default String representation of an object

The String returned by the default version
consists of the following:

  • The name of the class from which the object was instantiated
  • The @ character
  • A hexadecimal value that is the hashcode value for
    the object

As you can see, this does not include any information
about the values of the data stored in the object.

Other than the name of the class from which the
object was instantiated, this is not particularly useful to a human observer.

Dummy class does not override toString method

In this program, the class named Dummy
extends the Object class directly, and doesn’t override the toString()
method.

Therefore, when the toString() method is
invoked on a reference to an object of the Dummy class, the String
that is returned looks something like the following:

[email protected]

 

Answer 7


C.  3.5/9/true

Back to Question 7

Explanation 7


More on String concatenation

This program illustrates String concatenation.

The plus (+) operator is what is commonly called an
overloaded operator.

What is an overloaded operator

An overloaded operator is an operator whose behavior depends on the
types of its operands.

Plus (+) as a unary operator

The plus operator can be used as either a unary operator or a binary
operator.  However, as a unary operator, with only one operand to
its right, it doesn’t do anything useful.  This is illustrated by
the following two statements, which are functionally equivalent.

x = y;

x = +y;

Plus (+) as a binary operator

As a binary operator, the plus operator requires two operands, one on
either side.  (This is called infix notation.)  When used
as a binary operator, its behavior depends on the types of its operands.

Two numeric operands

If both operands are numeric operands, the plus operator performs arithmetic
addition.

If the two numeric operands are of different types, the narrower operand
is converted to the type of the wider operand, and the addition is performed
as the wider type.

Two String operands

If both operands are references to objects of type String, the
plus operator creates and returns a new String object that contains
the concatenated values of the two operands.

One String operand and one of another type

If one operand is a reference to an object of type String and
the other operand is of some type other than String, the plus operator 
causes a new String object to come into existence.

This new
String object is a String representation 
of the non-String operand,

Then it concatenates the two String objects, producing another
new String object, which is the concatenation of the two.

How is the new String operand created?

The manner in which it creates the new String object that represents
the non-String operand varies with the actual type of the operand.

A primitive operand

The simplest case is when the non-String operand is one of the
primitive types.  In these cases, the capability already exists to
produce a
String object that represents the value of the primitive
type.

A boolean operand

For example, if the operand is of type boolean, the new String
object that represents the operand will either contain the word true
or the word false.

A numeric operand

If the operand is one of the numeric types, the new String object
will be composed of some of the following:

  • numeric characters
  • a decimal point character
  • minus characters
  • plus character
  • other characters such as E or e

These characters will be arranged in such a way as to represent the numeric
value of the operand to a human observer.

In this program …

In this program, a numeric double value, a numeric int
value, and a boolean value were concatenated with a pair of slash
characters to produce a String object containing the following:

3.5/9/true

When a reference to this String object was passed as a parameter
to the println() method, the code in that method extracted the character
string from the String object, and displayed that character string
on the screen.

The toString method

If one of the operands to the plus operator is a reference to an object,
the toString method is invoked on the reference to produce a string
that represents the object.  The toString method may be overridden
by the author of the class from which the object was instantiated.

 

Answer 6


C.  4 -3

Back to Question 6

Explanation 6


A rounding algorithm

The method named doIt() in this program
illustrates an algorithm that can be used with a numeric cast operator
(int)
to cause double values to be rounded to the nearest integer.

Different than truncation toward zero

Note that this is different from simply truncating
to the next integer closer to zero (as was illustrated in Question 5).

Answer 5


D.  3 -3

Back to Question 5

Explanation 5


Truncates toward zero

When a double value is cast to an int, the fractional
part of the double value is discarded.

This produces a result that is the next integer value closer to zero.

This is true regardless of whether the double is positive or
negative.  This is sometimes referred to as its “truncation toward
zero”
behavior.

Not the same as rounding

If each of the values assigned to the variables named w and x
in this program were rounded to the nearest integer, the result would be
4 and -4, not 3 and -3 as produced by the program.

 

Answer 4


A.  Compiler Error

Back to Question 4

Explanation 4


Cannot cast a boolean type

A boolean type cannot be cast to any other
type.  This program produces the following compiler error:

Ap042.java:13: inconvertible types

found   : boolean

required: int

    int y = (int)x;

 

Answer 3


D.  B

Back to Question 3

Explanation 3


The logical and operator

The logical and operator (&&)
performs an and operation between  its two operands, which
must both be of type boolean.  If both operands are true, the
operator returns true.  Otherwise, it returns false.

The boolean negation operator (!)

The (!) operator is a unary operator,
meaning that it always has only one operand.  That operand must be
of type boolean, and the operand always appears immediately to the
right of the operator.

The behavior of this operator is to change its
right operand from true to false, or from false to
true.

Evaluation from inside out

Now, consider the following code fragment from
this program.


 

    int x = 5, y = 6;
    if(!(x < y) && !(y < x/0)){
      System.out.println("A");
    }else{
      System.out.println("B");
    }//end else

The individual operands of the &&
operator are evaluated from the inside out.

Consider the left operand of the &&
operator, which reads !(x<y).

(x < y) is true

In this case, x is less than y,
so the expression inside the parentheses evaluates to true.

!(x < y) is false

This true result becomes the right operand for
the ! operator at this point.

You might think of the state of the evaluation
process at this point as being something like !true.

When the ! operator is applied
to the true result, the combination of the two become a
false
result.

Short-circuit evaluation applies

This, in turn, causes the left operand of the
&&
operator to be false.

At that point, the final outcome of the logical
expression has been determined.  It doesn’t matter whether the right
operand is true or false.  The final result will be false regardless.

No attempt is made to evaluate the right operand

Therefore, no attempt is made to evaluate the
right operand of the && operator in this case.

No attempt is made to divide the integer variable
x
by zero, no exception is thrown, and the program doesn’t terminate abnormally. 
It runs to completion and displays a B on the screen.


 

Answer 2


C.  A

Back to Question 2

Explanation 2


Short-circuit evaluation

Question 1 was intended to set the stage for this question.

This Question, in combination with Question 1, is intended to help you
understand and remember the concept of short-circuit evaluation.

What is short-circuit evaluation?

Logical expressions are evaluated from left to right.  That is,
the left operand of a logical operator is evaluated before the right operand
of the same operator is evaluated.

When evaluating a logical expression, the final outcome can often be
determined without the requirement to evaluate all of the operands.

Once the final outcome is determined, no attempt is made to evaluate
the remainder of the expression.  This is short-circuit evaluation.

Code from Question 1

Consider the following code fragment from Question 1:

 

    int x = 5, y = 6;
    if((x > y) || (y < x/0)){
      ...

The (||) operator is the logical or operator.

Boolean operands required

This operator requires that its left and right operands both be of type
boolean
This operator performs an inclusive or on its left and right operands. 
The rules for an inclusive or are:

If either of its operands is true, the operator returns
true.  Otherwise, it returns false.

Left operand is false

In this particular expression, the value of x is not greater
than the value of y.  Therefore, the left operand of the logical
or
operator is not true.

Right operand must be evaluated

This means that the right operand must be evaluated in order to determine
the final outcome.

Right operand attempts to divide by zero

However, when an attempt is made to evaluate the right operand, an attempt
is made to divide x by zero.  This throws an exception, which
is not caught and handled by the program, so the program terminates as
described in Question 1.

Similar code from Question 2

Now consider the following code fragment from Question 2.

Note that the right operand of the logical or operator still
contains an expression that attempts to divide the integer x by
zero.

 

    int x = 5, y = 6;
    if((x < y) || (y < x/0)){
      System.out.println("A");
    ...

No runtime error in this case

This program does not terminate with a runtime error. Why not?

And the answer is …

In this case, x is less than y.   Therefore,
the left operand of the logical or operator is true.

Remember the rule for inclusive or

It doesn’t matter whether the right operand is true or false. 
The final outcome is determined as soon as it is determined that the left
operand is true.

The bottom line

Because the final outcome has been determined as soon as it is determined
that the left operand is true, no attempt is made to evaluate the right
operand.

Therefore, no attempt is made to divide x by zero, and no runtime
error occurs.

Short-circuit evaluation

This behavior is often referred to as short-circuit evaluation.

Only as much of a logical expression is evaluated as is required to
determine the final outcome.

Once the final outcome is determined, no attempt is made to evaluate
the remainder of the logical expression.

This is not only true for the logical or operator, it is also
true for the logical and (&&) operator.

 

Answer 1


B.  Runtime Error

Back to Question 1

Explanation 1


Divide by zero

Whenever a Java program attempts to evaluate an expression requiring
that a value of one of the integer types be divided by zero, it will throw
an
ArithmeticException.  If this exception is not caught and
handled by the program, it will cause the program to terminate.

Attempts to divide x by 0

This program attempts to evaluate the expression (y < x/0),
which attempts to divide the variable named x by zero.  This
causes the program to terminate with the following error message when running
under JDK 1.3:

java.lang.ArithmeticException: / by zero

 at Worker.doLogical(Ap039.java:13)

 at Ap039.main(Ap039.java:6)

About the author

Richard Baldwin
is a college professor (at Austin Community College in Austin, TX) and
private consultant whose primary focus is a combination of Java and XML.
In addition to the many platform-independent benefits of Java applications,
he believes that a combination of Java and XML will become the primary
driving force in the delivery of structured information on the Web.

Richard has participated in numerous consulting projects involving
Java, XML, or a combination of the two.  He frequently provides onsite
Java and/or XML training at the high-tech companies located in and around
Austin, Texas.  He is the author of Baldwin’s Java Programming Tutorials,
which has gained a worldwide following among experienced and aspiring Java
programmers. He has also published articles on Java Programming in Java
Pro magazine.

Richard holds an MSEE degree from Southern Methodist University and
has many years of experience in the application of computer technology
to real-world problems.

[email protected]

Latest Posts

Related Stories