Home > Articles > Programming > Java

This chapter is from the book

This chapter is from the book

Execution control

Java uses all of C’s execution control statements, so if you’ve programmed with C or C++, then most of what you see will be familiar. Most procedural programming languages have some kind of control statements, and there is often overlap among languages. In Java, the keywords include if-else, while, do-while, for, and a selection statement called switch. Java does not, however, support the much-maligned goto (which can still be the most expedient way to solve certain types of problems). You can still do a goto-like jump, but it is much more constrained than a typical goto.

true and false

All conditional statements use the truth or falsehood of a conditional expression to determine the execution path. An example of a conditional expression is A == B. This uses the conditional operator == to see if the value of A is equivalent to the value of B. The expression returns true or false. Any of the relational operators you’ve seen earlier in this chapter can be used to produce a conditional statement. Note that Java doesn’t allow you to use a number as a boolean, even though it’s allowed in C and C++ (where truth is nonzero and falsehood is zero). If you want to use a non-boolean in a boolean test, such as if(a), you must first convert it to a boolean value by using a conditional expression, such as if(a != 0).

if-else

The if-else statement is probably the most basic way to control program flow. The else is optional, so you can use if in two forms:

if(Boolean-expression)) 
  statement 

or

if(Boolean-expression)) 
  statement 
else 
  statement 

The conditional must produce a boolean result. The statement is either a simple statement terminated by a semicolon, or a compound statement, which is a group of simple statements enclosed in braces. Any time the word “statement” is used, it always implies that the statement can be simple or compound.

As an example of if-else, here is a test( ) method that will tell you whether a guess is above, below, or equivalent to a target number:

//: c03:IfElse.java 
import com.bruceeckel.simpletest.*; 

public class IfElse { 
  static Test monitor = new Test(); 
  static int test(int testval, int target) { 
    int result = 0; 
    if(testval > target) 
      result = +1; 
    else if(testval < target) 
      result = -1; 
    else 
      result = 0; // Match 
    return result; 
  } 
  public static void main(String[] args) { 
    System.out.println(test(10, 5)); 
    System.out.println(test(5, 10)); 
    System.out.println(test(5, 5)); 
    monitor.expect(new String[] { 
      "1", 
      "-1", 
      "0" 
    }); 
  } 
} ///:~ 

It is conventional to indent the body of a control flow statement so the reader can easily determine where it begins and ends.

return

The return keyword has two purposes: It specifies what value a method will return (if it doesn’t have a void return value) and it causes that value to be returned immediately. The preceding test( ) method can be rewritten to take advantage of this:

//: c03:IfElse2.java 
import com.bruceeckel.simpletest.*; 

public class IfElse2 { 
  static Test monitor = new Test(); 
  static int test(int testval, int target) { 
    if(testval > target) 
      return +1; 
    else if(testval < target) 
      return -1; 
    else 
      return 0; // Match 
  } 
  public static void main(String[] args) { 
    System.out.println(test(10, 5)); 
    System.out.println(test(5, 10)); 
    System.out.println(test(5, 5)); 
    monitor.expect(new String[] { 
      "1", 
      "-1", 
      "0" 
    }); 
  } 
} ///:~ 

There’s no need for else, because the method will not continue after executing a return.

Iteration

Looping is controlled by while, do-while and for, which are sometimes classified as iteration statements. A statement repeats until the controlling Boolean-expression evaluates to false. The form for a while loop is

while(Boolean-expression)) 
  statement 

The Boolean-expression is evaluated once at the beginning of the loop and again before each further iteration of the statement.

Here’s a simple example that generates random numbers until a particular condition is met:

//: c03:WhileTest.java 
// Demonstrates the while loop. 
import com.bruceeckel.simpletest.*; 

public class WhileTest { 
  static Test monitor = new Test(); 
  public static void main(String[] args) { 
    double r = 0; 
    while(r < 0.99d) { 
      r = Math.random(); 
      System.out.println(r); 
      monitor.expect(new String[] { 
        "%% \\d\\.\\d+E?-?\\d*" 
      }, Test.AT_LEAST); 
    } 
  } 
} ///:~ 

This uses the static method random( ) in the Math library, which generates a double value between 0 and 1. (It includes 0, but not 1.) The conditional expression for the while says “keep doing this loop until the number is 0.99 or greater.” Each time you run this program, you’ll get a different-sized list of numbers.

In the expect( ) statement, you see the Test.AT_LEAST flag following the expected list of strings. The expect( ) statement can include several different flags to modify its behavior; this one says that expect( ) should see at least the lines shown, but others may also appear (which it ignores). Here, it says “you should see at least one double value.”

do-while

The form for do-while is

do 
  statement 
while(Boolean-expression); 

The sole difference between while and do-while is that the statement of the do-while always executes at least once, even if the expression evaluates to false the first time. In a while, if the conditional is false the first time the statement never executes. In practice, do-while is less common than while.

for

A for loop performs initialization before the first iteration. Then it performs conditional testing and, at the end of each iteration, some form of “stepping.” The form of the for loop is:

for(initialization; Boolean-expression; step) 
  statement 

Any of the expressions initialization, Boolean-expression or step can be empty. The expression is tested before each iteration, and as soon as it evaluates to false, execution will continue at the line following the for statement. At the end of each loop, the step executes.

for loops are usually used for “counting” tasks:

//: c03:ListCharacters.java 
// Demonstrates "for" loop by listing 
// all the lowercase ASCII letters. 
import com.bruceeckel.simpletest.*; 

public class ListCharacters { 
  static Test monitor = new Test(); 
  public static void main(String[] args) { 
    for(int i = 0; i < 128; i++) 
      if(Character.isLowerCase((char)i)) 
        System.out.println("value: " + i + 
          " character: " + (char)i); 
    monitor.expect(new String[] { 
      "value: 97 character: a", 
      "value: 98 character: b", 
      "value: 99 character: c", 
      "value: 100 character: d", 
      "value: 101 character: e", 
      "value: 102 character: f", 
      "value: 103 character: g", 
      "value: 104 character: h", 
      "value: 105 character: i", 
      "value: 106 character: j", 
      "value: 107 character: k", 
      "value: 108 character: l", 
      "value: 109 character: m", 
      "value: 110 character: n", 
      "value: 111 character: o", 
      "value: 112 character: p", 
      "value: 113 character: q", 
      "value: 114 character: r", 
      "value: 115 character: s", 
      "value: 116 character: t", 
      "value: 117 character: u", 
      "value: 118 character: v", 
      "value: 119 character: w", 
      "value: 120 character: x", 
      "value: 121 character: y", 
      "value: 122 character: z" 
    }); 
  } 
} ///:~ 

Note that the variable i is defined at the point where it is used, inside the control expression of the for loop, rather than at the beginning of the block denoted by the open curly brace. The scope of i is the expression controlled by the for.

This program also uses the java.lang.Character “wrapper” class, which not only wraps the primitive char type in an object, but also provides other utilities. Here, the static isLowerCase( ) method is used to detect whether the character in question is a lower-case letter.

Traditional procedural languages like C require that all variables be defined at the beginning of a block so that when the compiler creates a block, it can allocate space for those variables. In Java and C++, you can spread your variable declarations throughout the block, defining them at the point that you need them. This allows a more natural coding style and makes code easier to understand.

You can define multiple variables within a for statement, but they must be of the same type:

for(int i = 0, j = 1; i < 10 && j != 11; i++, j++) 
  // body of for loop 

The int definition in the for statement covers both i and j. The ability to define variables in the control expression is limited to the for loop. You cannot use this approach with any of the other selection or iteration statements.

The comma operator

Earlier in this chapter I stated that the comma operator (not the comma separator, which is used to separate definitions and method arguments) has only one use in Java: in the control expression of a for loop. In both the initialization and step portions of the control expression, you can have a number of statements separated by commas, and those statements will be evaluated sequentially. The previous bit of code uses this ability. Here’s another example:

//: c03:CommaOperator.java 
import com.bruceeckel.simpletest.*; 

public class CommaOperator { 
  static Test monitor = new Test(); 
  public static void main(String[] args) { 
    for(int i = 1, j = i + 10; i < 5; 
        i++, j = i * 2) { 
      System.out.println("i= " + i + " j= " + j); 
    } 
    monitor.expect(new String[] { 
      "i= 1 j= 11", 
      "i= 2 j= 4", 
      "i= 3 j= 6", 
      "i= 4 j= 8" 
    }); 
  } 
} ///:~ 

You can see that in both the initialization and step portions, the statements are evaluated in sequential order. Also, the initialization portion can have any number of definitions of one type.

break and continue

You can also control the flow of the loop inside the body of any of the iteration statements by using break and continue. break quits the loop without executing the rest of the statements in the loop. continue stops the execution of the current iteration and goes back to the beginning of the loop to begin the next iteration.

This program shows examples of break and continue within for and while loops:

//: c03:BreakAndContinue.java 
// Demonstrates break and continue keywords. 
import com.bruceeckel.simpletest.*; 

public class BreakAndContinue { 
  static Test monitor = new Test(); 
  public static void main(String[] args) { 
    for(int i = 0; i < 100; i++) { 
      if(i == 74) break; // Out of for loop 
      if(i % 9 != 0) continue; // Next iteration 
      System.out.println(i); 
    } 
    int i = 0; 
    // An "infinite loop": 
    while(true) { 
      i++; 
      int j = i * 27; 
      if(j == 1269) break; // Out of loop 
      if(i % 10 != 0) continue; // Top of loop 
      System.out.println(i); 
    } 
    monitor.expect(new String[] { 
      "0", 
      "9", 
      "18", 
      "27", 
      "36", 
      "45", 
      "54", 
      "63", 
      "72", 
      "10", 
      "20", 
      "30", 
      "40" 
    }); 
  } 
} ///:~ 

In the for loop, the value of i never gets to 100 because the break statement breaks out of the loop when i is 74. Normally, you’d use a break like this only if you didn’t know when the terminating condition was going to occur. The continue statement causes execution to go back to the top of the iteration loop (thus incrementing i) whenever i is not evenly divisible by 9. When it is, the value is printed.

The second portion shows an “infinite loop” that would, in theory, continue forever. However, inside the loop there is a break statement that will break out of the loop. In addition, you’ll see that the continue moves back to the top of the loop without completing the remainder. (Thus printing happens in the second loop only when the value of i is divisible by 10.) In the output, The value 0 is printed, because 0 % 9 produces 0.

A second form of the infinite loop is for(;;). The compiler treats both while(true) and for(;;) in the same way, so whichever one you use is a matter of programming taste.

The infamous “goto”

The goto keyword has been present in programming languages from the beginning. Indeed, goto was the genesis of program control in assembly language: “If condition A, then jump here, otherwise jump there.” If you read the assembly code that is ultimately generated by virtually any compiler, you’ll see that program control contains many jumps (the Java compiler produces its own “assembly code,” but this code is run by the Java Virtual Machine rather than directly on a hardware CPU).

A goto is a jump at the source-code level, and that’s what brought it into disrepute. If a program will always jump from one point to another, isn’t there some way to reorganize the code so the flow of control is not so jumpy? goto fell into true disfavor with the publication of the famous “Goto considered harmful” paper by Edsger Dijkstra, and since then goto-bashing has been a popular sport, with advocates of the cast-out keyword scurrying for cover.

As is typical in situations like this, the middle ground is the most fruitful. The problem is not the use of goto, but the overuse of goto; in rare situations goto is actually the best way to structure control flow.

Although goto is a reserved word in Java, it is not used in the language; Java has no goto. However, it does have something that looks a bit like a jump tied in with the break and continue keywords. It’s not a jump but rather a way to break out of an iteration statement. The reason it’s often thrown in with discussions of goto is because it uses the same mechanism: a label.

A label is an identifier followed by a colon, like this:

label1: 

The only place a label is useful in Java is right before an iteration statement. And that means right before—it does no good to put any other statement between the label and the iteration. And the sole reason to put a label before an iteration is if you’re going to nest another iteration or a switch inside it. That’s because the break and continue keywords will normally interrupt only the current loop, but when used with a label, they’ll interrupt the loops up to where the label exists:

label1: 
outer-iteration { 
  inner-iteration { 
    //… 
    break; // 1 
    //… 
    continue;  // 2 
    //… 
    continue label1; // 3 
    //… 
    break label1;  // 4 
  } 
} 

In case 1, the break breaks out of the inner iteration and you end up in the outer iteration. In case 2, the continue moves back to the beginning of the inner iteration. But in case 3, the continue label1 breaks out of the inner iteration and the outer iteration, all the way back to label1. Then it does in fact continue the iteration, but starting at the outer iteration. In case 4, the break label1 also breaks all the way out to label1, but it does not reenter the iteration. It actually does break out of both iterations.

Here is an example using for loops:

//: c03:LabeledFor.java 
// Java's "labeled for" loop. 
import com.bruceeckel.simpletest.*; 

public class LabeledFor { 
  static Test monitor = new Test(); 
  public static void main(String[] args) { 
    int i = 0; 
    outer: // Can't have statements here 
    for(; true ;) { // infinite loop 
      inner: // Can't have statements here 
      for(; i < 10; i++) { 
        System.out.println("i = " + i); 
        if(i == 2) { 
          System.out.println("continue"); 
          continue; 
        } 
        if(i == 3) { 
          System.out.println("break"); 
          i++; // Otherwise i never 
               // gets incremented. 
          break; 
        } 
        if(i == 7) { 
          System.out.println("continue outer"); 
          i++; // Otherwise i never 
               // gets incremented. 
          continue outer; 
        } 
        if(i == 8) { 
          System.out.println("break outer"); 
          break outer; 
        } 
        for(int k = 0; k < 5; k++) { 
          if(k == 3) { 
            System.out.println("continue inner"); 
            continue inner; 
          } 
        } 
      } 
    } 
    // Can't break or continue to labels here 
    monitor.expect(new String[] { 
      "i = 0", 
      "continue inner", 
      "i = 1", 
      "continue inner", 
      "i = 2", 
      "continue", 
      "i = 3", 
      "break", 
      "i = 4", 
      "continue inner", 
      "i = 5", 
      "continue inner", 
      "i = 6", 
      "continue inner", 
      "i = 7", 
      "continue outer", 
      "i = 8", 
      "break outer" 
    }); 
  } 
} ///:~ 

Note that break breaks out of the for loop, and that the increment-expression doesn’t occur until the end of the pass through the for loop. Since break skips the increment expression, the increment is performed directly in the case of i == 3. The continue outer statement in the case of i == 7 also goes to the top of the loop and also skips the increment, so it too is incremented directly.

If not for the break outer statement, there would be no way to get out of the outer loop from within an inner loop, since break by itself can break out of only the innermost loop. (The same is true for continue.)

Of course, in the cases where breaking out of a loop will also exit the method, you can simply use a return.

Here is a demonstration of labeled break and continue statements with while loops:

//: c03:LabeledWhile.java 
// Java's "labeled while" loop. 
import com.bruceeckel.simpletest.*; 

public class LabeledWhile { 
  static Test monitor = new Test(); 
  public static void main(String[] args) { 
    int i = 0; 
    outer: 
    while(true) { 
      System.out.println("Outer while loop"); 
      while(true) { 
        i++; 
        System.out.println("i = " + i); 
        if(i == 1) { 
          System.out.println("continue"); 
          continue; 
        } 
        if(i == 3) { 
          System.out.println("continue outer"); 
          continue outer; 
        } 
        if(i == 5) { 
          System.out.println("break"); 
          break; 
        } 
        if(i == 7) { 
          System.out.println("break outer"); 
          break outer; 
        } 
      } 
    } 
    monitor.expect(new String[] { 
      "Outer while loop", 
      "i = 1", 
      "continue", 
      "i = 2", 
      "i = 3", 
      "continue outer", 
      "Outer while loop", 
      "i = 4", 
      "i = 5", 
      "break", 
      "Outer while loop", 
      "i = 6", 
      "i = 7", 
      "break outer" 
    }); 
  } 
} ///:~ 

The same rules hold true for while:

  1. A plain continue goes to the top of the innermost loop and continues.

  2. A labeled continue goes to the label and reenters the loop right after that label.

  3. A break “drops out of the bottom” of the loop.

  4. A labeled break drops out of the bottom of the end of the loop denoted by the label.

It’s important to remember that the only reason to use labels in Java is when you have nested loops and you want to break or continue through more than one nested level.

In Dijkstra’s “goto considered harmful” paper, what he specifically objected to was the labels, not the goto. He observed that the number of bugs seems to increase with the number of labels in a program. Labels and gotos make programs difficult to analyze statically, since it introduces cycles in the program execution graph. Note that Java labels don’t suffer from this problem, since they are constrained in their placement and can’t be used to transfer control in an ad hoc manner. It’s also interesting to note that this is a case where a language feature is made more useful by restricting the power of the statement.

switch

The switch is sometimes classified as a selection statement. The switch statement selects from among pieces of code based on the value of an integral expression. Its form is:

switch(integral-selector) {) { 
  case integral-value1 : statement; break; 
  case integral-value2 : statement; break; 
  case integral-value3 : statement; break; 
  case integral-value4 : statement; break; 
  case integral-value5 : statement; break; 
  // ... 
  default: statement; 
} 

Integral-selector is an expression that produces an integral value. The switch compares the result of integral-selector to each integral-value. If it finds a match, the corresponding statement (simple or compound) executes. If no match occurs, the default statement executes.

You will notice in the preceding definition that each case ends with a break, which causes execution to jump to the end of the switch body. This is the conventional way to build a switch statement, but the break is optional. If it is missing, the code for the following case statements execute until a break is encountered. Although you don’t usually want this kind of behavior, it can be useful to an experienced programmer. Note that the last statement, following the default, doesn’t have a break because the execution just falls through to where the break would have taken it anyway. You could put a break at the end of the default statement with no harm if you considered it important for style’s sake.

The switch statement is a clean way to implement multiway selection (i.e., selecting from among a number of different execution paths), but it requires a selector that evaluates to an integral value, such as int or char. If you want to use, for example, a string or a floating-point number as a selector, it won’t work in a switch statement. For non-integral types, you must use a series of if statements.

Here’s an example that creates letters randomly and determines whether they’re vowels or consonants:

//: c03:VowelsAndConsonants.java 
// Demonstrates the switch statement. 
import com.bruceeckel.simpletest.*; 

public class VowelsAndConsonants { 
  static Test monitor = new Test(); 
  public static void main(String[] args) { 
    for(int i = 0; i < 100; i++) { 
      char c = (char)(Math.random() * 26 + 'a'); 
      System.out.print(c + ": "); 
      switch(c) { 
        case 'a': 
        case 'e': 
        case 'i': 
        case 'o': 
        case 'u': System.out.println("vowel"); 
                  break; 
        case 'y': 
        case 'w': System.out.println("Sometimes a vowel"); 
                  break; 
        default:  System.out.println("consonant"); 
      } 
      monitor.expect(new String[] { 
        "%% [aeiou]: vowel|[yw]: Sometimes a vowel|" + 
          "[^aeiouyw]: consonant" 
      }, Test.AT_LEAST); 
    } 
  } 
} ///:~ 

Since Math.random( ) generates a value between 0 and 1, you need only multiply it by the upper bound of the range of numbers you want to produce (26 for the letters in the alphabet) and add an offset to establish the lower bound.

Although it appears you’re switching on a character here, the switch statement is actually using the integral value of the character. The single-quoted characters in the case statements also produce integral values that are used for comparison.

Notice how the cases can be “stacked” on top of each other to provide multiple matches for a particular piece of code. You should also be aware that it’s essential to put the break statement at the end of a particular case; otherwise, control will simply drop through and continue processing on the next case.

In the regular expression in this expect( ) statement, the ‘|’ is used to indicate three different possibilities. The ‘[]’ encloses a “set” of characters in a regular expression, so the first part says “one of a, e, i, o, or u, followed by a colon and the word ‘vowel’.” The second possibility indicates either y or w and: “Sometimes a vowel.” The set in the third possibility begins with a ‘^’, which means “not any of the characters in this set,” so it indicates anything other than a vowel will match.

Calculation details

The statement:

char c = (char)(Math.random() * 26 + 'a'); 

deserves a closer look. Math.random( ) produces a double, so the value 26 is converted to a double to perform the multiplication, which also produces a double. This means that ‘a’ must be converted to a double to perform the addition. The double result is turned back into a char with a cast.

What does the cast to char do? That is, if you have the value 29.7 and you cast it to a char, is the resulting value 30 or 29? The answer to this can be seen in this example:

//: c03:CastingNumbers.java 
// What happens when you cast a float 
// or double to an integral value? 
import com.bruceeckel.simpletest.*; 

public class CastingNumbers { 
  static Test monitor = new Test(); 
  public static void main(String[] args) { 
    double 
      above = 0.7, 
      below = 0.4; 
    System.out.println("above: " + above); 
    System.out.println("below: " + below); 
    System.out.println("(int)above: " + (int)above); 
    System.out.println("(int)below: " + (int)below); 
    System.out.println("(char)('a' + above): " + 
      (char)('a' + above)); 
    System.out.println("(char)('a' + below): " + 
      (char)('a' + below)); 
    monitor.expect(new String[] { 
      "above: 0.7", 
      "below: 0.4", 
      "(int)above: 0", 
      "(int)below: 0", 
      "(char)('a' + above): a", 
      "(char)('a' + below): a" 
    }); 
  } 
} ///:~ 

So the answer is that casting from a float or double to an integral value always truncates the number.

A second question concerns Math.random( ). Does it produce a value from zero to one, inclusive or exclusive of the value ‘1’? In math lingo, is it (0,1), or [0,1], or (0,1] or [0,1)? (The square bracket means “includes,” whereas the parenthesis means “doesn’t include.”) Again, a test program might provide the answer:

//: c03:RandomBounds.java 
// Does Math.random() produce 0.0 and 1.0? 
// {RunByHand} 

public class RandomBounds { 
  static void usage() { 
    System.out.println("Usage: \n\t" + 
      "RandomBounds lower\n\tRandomBounds upper"); 
    System.exit(1); 
  } 
  public static void main(String[] args) { 
    if(args.length != 1) usage(); 
    if(args[0].equals("lower")) { 
      while(Math.random() != 0.0) 
        ; // Keep trying 
      System.out.println("Produced 0.0!"); 
    } 
    else if(args[0].equals("upper")) { 
      while(Math.random() != 1.0) 
        ; // Keep trying 
      System.out.println("Produced 1.0!"); 
    } 
    else 
      usage(); 
  } 
} ///:~ 

To run the program, you type a command line of either:

java RandomBounds lower 

or

java RandomBounds upper 

In both cases you are forced to break out of the program manually, so it would appear that Math.random( ) never produces either 0.0 or 1.0. But this is where such an experiment can be deceiving. If you consider2 that there are about 262 different double fractions between 0 and 1, the likelihood of reaching any one value experimentally might exceed the lifetime of one computer, or even one experimenter. It turns out that 0.0 is included in the output of Math.random( ). Or, in math lingo, it is [0,1).

/content/images/chap3_0131002872/elementLinks/03icon01.gif

where b is the base (usually 2), p is the precision (digits in the mantissa), M is the largest exponent, and m is the smallest exponent. IEEE 754 uses:

/content/images/chap3_0131002872/elementLinks/03icon02.gif


so the total number of numbers is

/content/images/chap3_0131002872/elementLinks/03icon03.gif


Half of these numbers (corresponding to exponents in the range [-1022, 0]) are less than 1 in magnitude (both positive and negative), so 1/4 of that expression, or 2^62 - 2^52 + 1 (approximately 2^62) is in the range [0,1). See my paper at http://www.freshsources.com).

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020