Chapter 2: Introducing Data Types and Operators, pp. 35-70 |
Session 2Table of Data Types
Fundamentals
|
What does args represent?
The most important (and largest) integer type is int. The most important (and largest) floating type is double. Note that byte is 8 bits, whereas int is 32 bits.
Let's look at a primitive data type, byte:
How about the data type called int?
What is the data type of items that belong to args?
How do I determine how many decimal points in a calculation?
How do I get a square root?
In this session, we will look at some operators:
Scanner in conjunction with a for loop:
The output can be similar to the following:
How many strings do you want me to work with?
3
Type string number 1 and hit enter.
hello
You typed hello
Type string number 2 and hit enter.
there
You typed there
Type string number 3 and hit enter.
Tom
You typed Tom
You typed hellothereTom
The Scanner class, http://docs.oracle.com/javase/7/docs/api/ , provides methods to get integers from the user.
What is special about the byte data type:
Comparison of the size of the primitive data types.
Data types are types of data, such as whole numbers (integer types), numbers with decimal points (floating point types), characters (char), and boolean (true, false).
Which data types are in the following program?
The most important (and largest) integer type is int. The most important (and largest) floating type is double.
A data type is the characteristic of a variable that determines what kind of data it can hold. Java is a strongly-typed language because it requires that every variable and expression have a type. The Java compiler checks for type compatibility among the variables to which you assign values. The Java compiler has a parser and debugger that alerts you of any type mismatch, and you have to fix it before your program will compile.
Although javac generally requires you to specify the data type, for convenience, printing out the primitive types is an exception. For example, javac implicitly assigns a datatype at compile-time for the print and println methods:
A given variable is either a primitive (basic type) or an object (custom
type).
Each primitive data type has a range of values, which determines its relatively
small size in
memory. (Objects can grow quite large.)
http://java.sun.com/docs/books/tutorial/java/nutsandbolts/variables.html
Each primitive type has a corresponding class. For example, a variable of type byte corresponds to the Byte class. The corresponding class has a static, final field, MAX_VALUE, that represents the maximum value of that type. What must this field be static? Why should it be final?
The output is:
Whole numbers without decimals (no floating point). The type used for counters in loops is int.
Type | Size | Range | Example |
Integer types | |||
byte | 8 bits | -128 to 127
-28 to (28-1) |
Colors (RGB) ASCII characters |
short | 16 bits | -32,768 to 32,767
-216 to (216-1) |
Unicode (world languages) |
int | 32 bits | -232 to (232-1) | counters in loops |
long | 64 bits | -264 to (264-1) | big numbers |
Can be float or double, but double is the most important because it is larger and more precise. Most devices have enough memory to use double instead of float.
Floating point types | |||
float | 32 bits (6 digits) | 3.40282e+38 | floating point (currency, temperature, percentage, length) |
double | 64 bits (15 digits) | 1.79769e+308 | double (large numbers or high precision, such as for
astronomy or subatomic physics)
The java compiler expects you will perform division by using double instead of float. |
A single character, char, is primitive, but a String instance is an object with methods on it.
Special types | |||
char | 16 bits (2 bytes) | Unicode characters (whereas other languages use 1-byte ASCII text characters) http://www.unicode.org/unicode/standard/WhatIsUnicode.html |
alphabets and numerals |
The alphabet is an ordered collection of letters that represent, for the computer, a numerical sequence.
One the primitive data types is char, for character. Each character on the keyboard has a numeric value. Capital "A" is 65 and lower-case "a" is 97. The ASCII table uses 8-bits (2 *2 eight times = 256) to store values adequate for languages uses characters based on those of Latin, such as German, French, and English. The numeric value underlying each character on the keyboard can be used to do arithmetic. For example, adding 32 to "A" results in "a".
The output is the same as that of the program below, which uses the numerical equivalent of the char.
Another example:
Note: To support languages that do not use characters based on Latin, such as Sanskrit, Mandarin, Japanese, Korean, Greek, Cyrillic, Arabic, Hebrew, and even ancient Egyptian hieroglyphs, Java uses 16-bit Unicode. Java (the programming language), therefore, supports the Javanese character set, the pre-Colonial writing system of Java (the island). Some people on Java know Java, and Java can work with Javanese.
A boolean value (either true or false) is not a literal String (neither "true" nor "false") even though it looks like a String without quotation marks.
Special types | |||
boolean | Java reserves 8 bits but only uses 1 | true false Note: These values are keywords. |
logic test with if |
A variable is a name for a piece of memory that stores a value. Each variable must have a name. For example,
int BOILING_POINT = 100;
BOILING_POINT is the variable of type int and 100 is its literal value, a valid integer value.
Unlike JavaScript and Visual Basic, Java is a strongly-typed programming language.
Numbers are represented in memory using bits. A bit is the smallest unit that
a computer can work with. A bit has two possible values,
0 or 1.
Everything in a computer is represented by bits.
A number is represented by a series of bits which represent different powers of
2.
An 8 bit-number is called a byte:
Value of the number in decimal digits | Bits (value in binary digits) - to the power of |
0 | 00000000 |
1 | 00000001 = 2^0 |
4 | 00000100 = 2^2+0^1+0^0 |
8 | 00001000 = 2^3+0^2+0^1+0^0 |
13 = 8 + 4 + 1 | 00001101 = 2^3+2^2+0^1+2^0 |
255 = 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 | 11111111 = ... |
A constant variable is a variable that is assigned a value once and
the constant value cannot be changed afterward (during execution of the program).
The compiler
optimizes a constant for memory storage and performance. The keyword
final signals that the value is fixed.
Examples of possible constants
A variable is a name (or reference) for a
storage area in memory for a value that can change.
A literal is the
direct representation of a value.
Boolean | Boolean myBool =
true; Boolean defaultValue = false; (no quotation marks because a Boolean is not a String) |
character | any character in the 16-bit Unicode character set a character literal is enclosed within single quotation marks char myChar = 'z'; |
String | a string object (strings are a special object type in Java
that is implemented as an array of chars, the primitive type for a character).
A String literal has double quotation marks: String greeting = "Hello!"; |
number | int yearsOnTheJob =
17; double inflationRate = .0306; |
double sum = 382.36; // sum is a variable, not a literal
String firstName = "Luke"; // "Luke" is a string literal inside quotation marks
boolean isExpensive = false; // booleans are not string literals
\n new line
\t tab
System.out.println("Let's make a \nnew line and a \ttab here.");
To summarize, the escape sequence for a new line is \n and for a tab is \t
http://java.sun.com/docs/books/tutorial/java/javaOO/variables.html
The expression (an expression is a part of a statement that returns a single value) that initializes a variable (that assigns it a value for initial use) can be an expression with:
In this example, the declaration statement on line 6 is also an expression whose return value initializes the newly declared variable.
A block of code is whatever is within a set of curly braces.
{ // open curly brace
{ // close curly brace
{ // start of
code block
// declarations, assignments, control statements, and so on
} // end of code block
Think of a code block as a unit of code. Just as an English sentence can have many clauses and commas, but still be a single unit (the sentence), so many lines of code can belong to a single code block. A class definition resides a code block. We have seen how within a class definition code block, we can have code blocks for a for loop. An if statement can also have multiple statements within its code block.
if (s.length() > s2.length() { // if true, execute both statements in the block
System.out.println("s is longer than s2.");
System.out.println("s2 is shorter than s.");
}
TIP: When you begin a code block, type both the beginning curly brace and the ending curly brace before you fill in the block with code. That way you will not forget to close your code block.
The "scope" of a variable is defined by the code block in which it resides. Scope defines the visibility of variables.
Java can only work with variables that it
are "in scope".
Scope is the block of code in which a variable exists and
is available for use.
The scope (or visibility) of a variable depends upon WHERE you declare it.
You might declare a variable within a block of code that is a:
Another example:
The output is:
QUESTION: Which line numbers define the scope of x? of y?
Sun's tutorial exposes a common error involving the concept of scope:
if (...) {
int myInteger = 17;
...
}
System.out.println("The value of myInteger = " + myInteger); // error
The final line won't compile because the local variable
myInteger
is out
of scope. The scope of myInteger
is the block of code between the {
and }
.
The myInteger variable does not exist after the
closing curly brace (})
ends
that block of code.
QUESTION: Can you have an instance variable with exactly the same name as a local variable?
I don't want to delve into static too much yet, but here we have a static variable that is in scope anywhere in the class.
Let's discuss this example:
and its output:
Value of myInteger is: 1
Value of myInteger is: 2
3 is a multiple of 3
Value of myInteger is: 3
Value of myInteger is: 4
Value of myInteger is: 5
6 is a multiple of 3
Value of myInteger is: 6
Value of myInteger is: 7
Value of myInteger is: 8
9 is a multiple of 3
Value of myInteger is: 9
Operator | Name | Use | Description |
---|---|---|---|
+ |
addition | op1 + op2 |
Adds op1 and op2 |
- |
subtraction | op1 - op2 |
Subtracts op2 from op1 |
* |
multiplication | op1 * op2 |
Multiplies op1 by op2 |
/ |
division | op1 / op2 |
Divides op1 by op2 |
% |
modulus | op1 % op2 |
Computes the remainder of dividing op1 by op2 |
The program finds the integers between 1 and 100 that are a multiple of 13.
Note that I decrement instead of increment by using -- instead of ++.
The output is:
Normally, we increment in post-fix fashion, AFTER evaluation of a variable value, such as c++
Prefix incrementing BEFORE evaluating the value of a variable would be written in a manner like this: ++c
For example,
The output is:
10
10
11
11
12
12
20
21
21
22
22
23
Another example follows.
The output is:
count: 0
count after prefix: 1
count after postfix: 2
count after prefix: 3
count after postfix and end of first loop: 4
Prefix and postfix are the same here because there is no operator, such as assig
nment
count: 5
count after prefix: 6
count after postfix: 7
count after prefix: 8
count after postfix and end of first loop: 9
count at beginnng of 2nd loop: 0
Prefix and postfix are different here because of assignment
pre shows increment now: 1
post shows increment later: 1
pre show increment now: 3
post shows increment later: 3
count at beginnng of 2nd loop: 5
Prefix and postfix are different here because of assignment
pre shows increment now: 6
post shows increment later: 6
pre show increment now: 8
post shows increment later: 8
RELATIONAL OPERATORS | LOGICAL OPERATORS |
>
greater than >= greater than or equal to < less than <= less than or equal to == equal to != not equal to |
&
AND means both operands must be
true
to get true | OR means either or both operands must be true to get true && shortcircuit AND means stop evaluating if the left operand is false || shortcircuit OR means stop evaluating if the left operand is true |
The relational operators are different from the logical operators.
The relational operators compare the value of two operands
numerically. Logical
operators deal with booleans.
The logical operators (p. 55) are used when evaluating whether a condition is
true or false.
The logical operators are:
In certain situations, performance improves if the evaluation process is more simple. If you are checking for both A and B must be true, then if A is false, why spend time checking whether B is false? If all you care about is whether A or B is true, and A is true, why spend time checking whether B is true? Sometimes you might care about both A and B are true, so there is still a use case for the non-short circuit AND. However, short-circuit evaluation is not always faster (http://en.wikipedia.org/wiki/Short-circuit_evaluation#Possible_performance_penalty) and both kinds of evaluation are supported.
Whereas & is the normal AND operator, && is the short-circuit AND operator. (It takes longer to write the short-circuit version)
Similarly, whereas | is the normal OR operator, || is the short-circuit OR operator.
In this example, we avoid the program crashing if we use the short-circuit operator.
In this example, line 10 increments a value and tests a value. which is probably not a best practice:
Do not confuse the assignment operator = with the equals to comparison operator ==
int myInt = 7; // assignment
if (yourInt == myInt)
{
System.out.println("Two variables represent the same literal
value"):
}
x += 10; means x = x
+ 10;
x -= 10; means x = x
- 10;
x /= 10; means x = x
/ 10;
x *= 10; means x = x *
10;
x %= 10; means x = x %
10;
One use case is to have running total, such as
currentTotal += nextItem;
What is the difference between a comment, a statement, and an expression?
A statement is a command that you write in your program.
Syntax: a statement must end with a semicolon (;) so that the parser in the Java
compiler (javac) knows this is the end of your statement.
System.out.println("Hello Luke"); // pass a string argument to a method
double bodyTemperature = 98.6; // assign a value to a primitive variable
HumanBeing.inalienableRight = pursuitOfHappiness; // assign a value to a property of an object
Comments are for human code readers. The compiler ignores comments.
Insert comments in your code so that you, and others who will use your code, know
what the code is about.
Good comments make code more maintainable, even for the original programmer.
It is more common for code to have too few comments than too many comments.
In the preceding statements, a comment follows each statement.
Two slash characters (//) define the comment through the end of the current
line.
/* A slash followed by an asterisk
defined the beginning of a multi-line comment,
which ends with the reverse, an asterisk, followed by a slash */
An expression is a statement that returns a value.
In both examples below, the Java virtual machine will:
sum = priceOfItem1 + priceOfItem2; // the return value is stored in the variable sum
selfEvidentTruth = HumanBeing.IsCreatedEqual(); // boolean return value must be true or false
What is the difference between a declaration and an assignment?
A variable is a named location in memory. A declaration is a statement that lets the compiler know that we are going to use a variable to refer to a value of a certain type. Syntax requires that we declare the type before we declare the variable's name.
int temperature;
float drunk;
final int BOILING_POINT;
char[] daysOfTheWeek;
String[] myDays;
The declaration statement can be separate from the assignment statement.
The assignment operator is =
The operand to the left of the assignment operator is assigned (or gets) the
value of the operand to the right of the assignment operator.
int temperature;
temperature = 100; // the temperature variable "gets" the value of 100
double temperature;
temperature = 100.0001;
An assignment gives (assigns) a value to a variable. Typically, in Java, we
assign a value to a variable when we declare that variable.
However, we can assign a value later. And, we can re-assign a value still later,
unless the variable is a constant (keyword final).
int temperature = 70; //
Fahrenheit
float drunk = .01; // in percent
final int BOILING_POINT = 212; // a constant is final: no
reassignment
// We will learn about arrays in detail later.
// What follows is an array of characters
// for the 7 days of the week.
// (Single quotes are for chars.)
// Each element has a unique index.
// The first 's' (Sunday) has the index of zero.
// The second 's' (Saturday) has the index of 6.
char[] daysOfTheWeek = {'s', 'm', 't', 'w', 't', 'f', 's'};
// Use double quotes for strings.
String[] myDays = {"Sunday", "Monday", "Tuesday"};
Page 64 has the table of Operator Precedence. Key details include:
multiplication (*), division (/), and modulus (%) before addition (+) and
subtraction (-).
TIP: To ensure addition and subtraction precede multiplication,
put the addition and subtraction in parentheses.
A cast involves parentheses and therefore is a bit similar to a method call, but all it does is temporarily pretend the right operand is of the type inside the parentheses.
myInt = (int) myDouble;
In ordinary language, we might say that an actor is being cast in a part, but the human being that is the actor does not actually change, as does that have the characteristics of the casted role after the show is over.
A cast operation on a variable does not change the value of the variable being casted.
You can cast an int as a double to allow for more precision with division, that is, to allow for fractions..
Automatic conversion occurs when your expression involves two data types that are compatible with each other, and the conversion is widening, that is, the destination type accommodates larger values the the source type.
For example,
double myInteger = 1; // widen an integer to a double
double myFloat = 1.0; // widen a float to a double
I do not need to use all the memory it takes to store a double (64 bits) if my value is just an integer (32 bits), but Java allows me to make an assignment that involves this explicit conversion.
Java can "promote" data types when it evaluates an expression.
As the comments state, a byte can be promoted to a float, a char to an integer, a short to a double, an int to a float, and a float to a double.
Casting is the explicit translation of:
In a cast, the Java runtime knows enough about the types and how they are related to do this conversion.
byte, short, int, long, float, double | cast to/from | byte, short, int, long, float, double |
A widening cast is from a smaller type to a larger type.
A cast from a larger type to a smaller type must be explicit.
The syntax is (targetTypename)valueToCast
Line 9 casts the product of two doubles as an integer.
The output is:
The product as double is 3.75
The product as integer is = 3
Another explicit cast is of integer into byte:
b = (byte) (50 * 2);
Booleans cannot be cast.
When you cast a floating point type to an integer type, or a double to a
float, loss of precision might occur.
For example, (int)3.2
truncates the .2 and returns 3.
Also, when you cast from a larger integer type to a smaller one, if the number
is very large, it might be truncated and return a smaller number, or even wrap
around (as byte does) to its beginning.
The output is:
Conversion of int to byte.
When int i = 258 is cast as a byte, the byte value is: 1
Conversion of double to int.
Truncation when double 323.142 is cast as int: 323
Conversion of double to byte.
Casting double 323.142 into byte causes wraparound after 255: 67
Note: Just imagine the porting issue if different platforms dealt differently with the issue of overstepping the limit of the byte data type. One platform might convert the byte back to a double. Another might assign a value of zero. Another platform might crash the program. Still another might hang.
An operation involving two byte value causes the resulting byte value to be promoted to int. (p. 67)
To avoid integer overflow during integer multiplication, if an int is multiplied by a double, Java automatically promotes the int to double for the calculation. This is safe because no loss of precision can occur. In 1996, had the European spaceship, Ariane, been using Java code instead of Ada code, the control software would not have crashed from an overflow of the integer type, and the spaceship itself would not have crashed, a mere 37 seconds after its initial launch. http://en.wikipedia.org/wiki/Ariane_5_Flight_501 (It might, however, have landed in Lake Merritt.)