0% found this document useful (0 votes)
2 views

Java Bloch

Uploaded by

mcknucklecuck
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Java Bloch

Uploaded by

mcknucklecuck
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 45

Principles of Software Construction:

Objects, Design, and Concurrency

Introduction to Java

Josh Bloch Charlie Garrod

17-214 1
Administrivia
• Homework 1 due next Thursday 11:59 p.m. EST
– Everyone must read and sign our collaboration policy
• First reading assignment due Tuesday
– Effective Java Items 15 and 16

17-214 2
Outline
I. "Hello World!" explained
II. The type system
III. Quick ‘n’ dirty I/O

17-214 3
The “simplest” Java Program
class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}

17-214 4
Complication 1: you must use a class even if
you aren’t doing OO programming
class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}

17-214 5
Complication 2: main must be public
class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}

17-214 6
Complication 3: main must be static
class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}

17-214 7
Complication 4: main must return void
class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}

17-214 8
Complication 5: main must declare command
line arguments even if it doesn’t use them
class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}

17-214 9
Complication 6: println uses the static
field System.out
class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}

17-214 10
Execution is a bit complicated, too
• First you compile the source file
– javac HelloWorld.java
– Produces class file HelloWorld.class
• Then you launch the program
– java HelloWorld
– Java Virtual Machine (JVM) executes main method

17-214 11
On the bright side…
• Java has many good points to balance shortcomings
• Some verbosity is not a bad thing
– Can reduce errors and increase readability
• Modern IDEs eliminate much of the pain
– Type psvm instead of public static void main
• Managed runtime (VM) has many advantages
– Safe, flexible, obviates need for manual memory mgt.
• It may not be best language for Hello World…
– But Java is very good for large-scale programming!
17-214 12
Outline
I. “Hello World!” explained
II. The type system
III. Quick ‘n’ dirty I/O

17-214 13
Java has a bipartite (2-part) type system
Primitives Object Reference Types
int, long, byte, short, Everything else: classes, interfaces,
char, float, double, boolean arrays, enums, annotations
No identity except their value Have identity distinct from value
Immutable Some mutable, some immutable
On heap (local variables) or On heap, garbage collected
stack (object or class fields)
Can’t achieve unity of expression Unity of expression with generics
Dirt cheap More costly

17-214 14
Programming with primitives
A lot like C!
public class TrailingZeros {
public static void main(String[] args) {
int i = Integer.parseInt(args[0]);
System.out.println(numTrailingZerosInFactorial(i));
}

static int numTrailingZerosInFactorial(int i) {


int result = 0; // Conventional name for return value

while (i >= 5) {
i /= 5; // Same as i = i / 5; Remainder discarded
result += i;
}
return result;
}
}

17-214 15
Primitive type summary
• int 32-bit signed integer
• long 64-bit signed integer
• byte 8-bit signed integer
• short 16-bit signed integer
• char 16-bit unsigned integer/character
• float 32-bit IEEE 754 floating point number
• double 64-bit IEEE 754 floating point number
• boolean Boolean value: true or false

17-214 16
“Deficient” primitive types
• byte, short – typically use int instead!
– byte is broken – should have been unsigned
• float – typically use double instead!
– Provides too little precision
– Few compelling use cases
• large arrays in resource-constrained environments
• Machine learning (but JVM doesn’t necessarily give you
sufficient control for this: requires vector instructions)

17-214 17
Pop Quiz!

17-214 18
What does this fragment print?
int[] a = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

int i;
int sum1 = 0;
for (i = 0; i < a.length; i++) {
sum1 += a[i];
}

int j;
int sum2 = 0;
for (j = 0; i < a.length; j++) {
sum2 += a[j];
}

System.out.println(sum1 - sum2);

17-214 19
Maybe not what you expect!
int[] a = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

int i;
int sum1 = 0;
for (i = 0; i < a.length; i++) {
sum1 += a[i];
}
int j;
int sum2 = 0;
for (j = 0; i < a.length; j++) { // Copy/paste error!!!
sum2 += a[j];
}
System.out.println(sum1 - sum2);

You might expect it to print 0, but it prints 55

17-214 20
You could fix it like this…
int[] a = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

int i;
int sum1 = 0;
for (i = 0; i < a.length; i++) {
sum1 += a[i];
}
int j;
int sum2 = 0;
for (j = 0; j < a.length; j++) {
sum2 += a[j];
}

System.out.println(sum1 - sum2); // Now prints 0, as expected

17-214 21
But this fix is far better…
idiomatic Java for loop
int sum1 = 0;
for (int i = 0; i < a.length; i++) {
sum1 += a[i];
}

int sum2 = 0;
for (int i = 0; i < a.length; i++) {
sum2 += a[i];
}

System.out.println(sum1 - sum2); // Prints 0, as expected

• Reduces scope of index variable to the loop


• Shorter and less error prone
17-214 22
This fix is better still!
for-each loop
int sum1 = 0;
for (int x : a) {
sum1 += x;
}

int sum2 = 0;
for (int x : a) {
sum2 += x;
}

System.out.println(sum1 - sum2); // Prints 0, as expected

• Eliminates scope of index variable entirely!


• Even shorter and less error prone
17-214 23
Lessons from the quiz
• Minimize scope of local variables [EJ Item 57]
• Declare variables at point of use
• Initialize variables in declaration
• Prefer for-each loops to regular for-loops
• Use common idioms
• Watch out for bad smells in code
– Such as index variable declared outside loop

17-214 24
Objects
• All non-primitives are represented by objects.
• An object is a bundle of state and behavior
• State – the data contained in the object
– In Java, these are called its instance fields
• Behavior – the actions supported by the object
– In Java, these are called its methods
– Method is just OO-speak for function
– “Invoke a method” is OO-speak for “call a function”

17-214 25
Classes
• Every object has a class
– A class defines methods and fields
– Methods and fields collectively known as members
• Class defines both type and implementation
– Type ≈ what object does (hence where it can be used)
– Implementation ≈ how the object does things
• Loosely speaking, the methods of a class define
its Application Programming Interface (API)
– Defines how users interact with its instances

17-214 26
The Java class hierarchy
• The root is Object (all non-primitives are objects)
• All classes except Object have one parent class (AKA direct superclass)
– Specified with an extends clause
class Guitar extends Instrument { ... }
– If extends clause omitted, defaults to Object
• A class is an instance of all its superclasses

Object
Instrument Toy

Guitar Yoyo

17-214 27
Implementation inheritance
• A class:
– Inherits visible fields and methods from its superclasses
– Can override methods to change their behavior
• i.e., subtype can provide new implementations of superclass methods
• Known as subtype polymorphism

• Overriding method implementation must obey the


contract(s) of its superclass(es)
– Ensures subclass can be used anywhere superclass can
– Liskov Substitution Principle (LSP)
– We will talk more about this in a later class

17-214 28
Interface types
• Defines a type without an implementation
• Much more flexible than class types
– An interface can extend one or more others
– A class can implement multiple interfaces
Instrument

Stringed Electric
Instrument Instrument

Acoustic Electric
Synthesizer
Guitar Guitar

17-214 29
Enum types
• Java has object-oriented enums
• In simple form, they look just like C enums:
enum Planet { MERCURY, VENUS, EARTH, MARS,
JUPITER, SATURN, URANUS, NEPTUNE }

• But they have many advantages!


– Compile-time type safety
– Multiple enum types can share value names
– Can add or reorder without breaking existing uses
– High-quality Object methods are provided
– Screaming fast collections (EnumSet, EnumMap)
– Can access all constants of an enum (e.g. Planet.values())

17-214 30
Boxed primitives
• Immutable containers for primitive types
• Boolean, Integer, Short, Long, Character,
Float, Double
• Let you “use” primitives in contexts requiring objects
• Canonical use case is collections
– e.g., Map<String, Integer>
• Don’t use boxed primitives unless you have to!
• Language does autoboxing and auto-unboxing
– Blurs but does not eliminate distinction
– There be dragons!
17-214 31
Comparing values
x == y compares x and y “directly”:
primitive values: returns true if x and y have the same value
objects references: returns true if x and y refer to same object
x.equals(y) typically compares the values of
the objects referred to by x and y*

* Asuming it makes sense to do so for the objects in question

17-214 32
True or false?

int i = 5;
int j = 5;
System.out.println(i == j);
---------------------------

17-214 33
True or false?

int i = 5;
int j = 5;
System.out.println(i == j);
---------------------------
true

i 5

j 5

17-214 34
True or false?

int i = 5; String s = "foo";


int j = 5; String t = s;
System.out.println(i == j); System.out.println(s == t);
--------------------------- ---------------------------
true

i 5

j 5

17-214 35
True or false?

int i = 5; String s = "foo";


int j = 5; String t = s;
System.out.println(i == j); System.out.println(s == t);
--------------------------- ---------------------------
true true

i 5 s

j 5 t

"foo"

17-214 36
True or false?
String u = "iPhone";
int i = 5; String s = "foo"; String v = u.toLowerCase();
int j = 5; String t = s; String w = "iphone";
System.out.println(i == j); System.out.println(s == t); System.out.println(v == w);
--------------------------- --------------------------- ---------------------------
true true

i 5 s

j 5 t

"foo"

17-214 37
True or false?
String u = "iPhone";
int i = 5; String s = "foo"; String v = u.toLowerCase();
int j = 5; String t = s; String w = "iphone";
System.out.println(i == j); System.out.println(s == t); System.out.println(v == w);
--------------------------- --------------------------- ---------------------------
true true Undefined! (false in practice)

u "iPhone"
i 5 s

j 5 t v "iphone"
?

"foo" w "iphone"

17-214 38
The moral
• Always use .equals to compare object refs!
– (Except for enums, which are special)
– The == operator can fail silently and unpredictably
when applied to object references
– Same goes for the != operator

17-214 39
Outline
I. “Hello World!” explained
II. The Java type system
III. Quick ‘n’ dirty I/O

17-214 40
Console output
• Unformatted
System.out.println("Hello World");
System.out.println("Radius: " + r); // String concatenation
System.out.println(r * Math.cos(theta));// Param type is double
System.out.println(); // No param, prints a blank line
System.out.print("*"); // Doesn’t print line separator

• Formatted – very similar to C


System.out.printf("%d * %d = %d%n", a, b, a * b); // Varargs

17-214 41
Command line input (& console output)
Echos all its command line arguments

class Echo {
public static void main(String[] args) {
for (String arg : args) {
System.out.print(arg + " ");
}
System.out.println();
}
}

$ java Echo Woke up this morning, had them weary blues


Woke up this morning, had them weary blues

17-214 42
Command line input with parsing
Prints the GCD of its two command line arguments

class Gcd {
public static void main(String[] args) {
int i = Integer.parseInt(args[0]);
int j = Integer.parseInt(args[1]);
System.out.println(gcd(i, j));
}

static int gcd(int i, int j) {


return i == 0 ? j : gcd(j % i, i);
}
}

$ java Gcd 11322 35298


666

17-214 43
Console input with Scanner
Counts the words on standard input

class Wc {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long count = 0;
while (sc.hasNext()) {
sc.next(); // Swallow token
count++;
}
System.out.println(count);
}
}

$ java Wc < Wc.java


32

17-214 44
Summary
• Java is well suited to large programs; for small
ones, it may seem a bit verbose
• Bipartite type system – primitives and object refs
• Single implementation inheritance
• Multiple interface inheritance
• A few simple I/O techniques go a long way

17-214 55

You might also like