Essential Java classes mainly classes in the java

  • Slides: 92
Download presentation
Essential Java classes mainly classes in the java. lang and java. io packages

Essential Java classes mainly classes in the java. lang and java. io packages

Contents • • • Handling errors using exceptions Multi-threading I/O Setting program attributes Accessing

Contents • • • Handling errors using exceptions Multi-threading I/O Setting program attributes Accessing system resources

Exceptions • The Java programming language uses exceptions to provide error-handling capabilities for its

Exceptions • The Java programming language uses exceptions to provide error-handling capabilities for its programs • An exception is an event that occurs during the execution of a program that disrupts the normal flow of instructions • When an error occurs within a method, the method creates an object and hands it off to the runtime system • The object, called an exception object, contains information about the error, including its type and the state of the program when the error occurred • Creating an exception object and handing it to the runtime system is called throwing an exception

Exception handling

Exception handling

 • //Note: This class won't compile by design! import java. io. *; import

• //Note: This class won't compile by design! import java. io. *; import java. util. Vector; public class List. Of. Numbers { private Vector victor; private static final int SIZE = 10; public List. Of. Numbers () { victor = new Vector(SIZE); for (int i = 0; i < SIZE; i++) { victor. add. Element(new Integer(i)); } } public void write. List() { Print. Writer out = new Print. Writer( new File. Writer("Out. File. txt")); for (int i = 0; i < SIZE; i++) { out. println("Value at: " + i + " = " + victor. element. At(i)); } out. close(); } }

 • private Vector victor; private static final int SIZE = 10; Print. Writer

• private Vector victor; private static final int SIZE = 10; Print. Writer out = null; try { System. out. println("Entered try statement"); out = new Print. Writer(new File. Writer("Out. File. txt")); for (int i = 0; i < SIZE; i++) { out. println("Value at: " + i + " = " + victor. element. At(i)); } } catch and finally statements. . .

Catch exceptions • try { } catch (File. Not. Found. Exception e) { System.

Catch exceptions • try { } catch (File. Not. Found. Exception e) { System. err. println("File. Not. Found. Exception: " + e. get. Message()); throw new Sample. Exception(e); } catch (IOException e) { System. err. println("Caught IOException: " + e. get. Message()); }

Finally • finally { if (out != null) { System. out. println("Closing Print. Writer");

Finally • finally { if (out != null) { System. out. println("Closing Print. Writer"); out. close(); } else { System. out. println("Print. Writer not open"); } }

Specify exceptions thrown by methods • public void write. List() throws IOException { Print.

Specify exceptions thrown by methods • public void write. List() throws IOException { Print. Writer out = new Print. Writer( new File. Writer("Out. File. txt")); for (int i = 0; i < SIZE; i++) { out. println("Value at: " + i + " = " + victor. element. At(i)); } out. close(); }

Throw exceptions • public Object pop() throws Empty. Stack. Exception { Object obj; if

Throw exceptions • public Object pop() throws Empty. Stack. Exception { Object obj; if (size == 0) { throw new Empty. Stack. Exception(); } obj = object. At(SIZE - 1); set. Object. At(SIZE - 1, null); size--; return obj; }

Exception classes

Exception classes

Chained exceptions • Relevant constructor and methods – – Throwable get. Cause() Throwable init.

Chained exceptions • Relevant constructor and methods – – Throwable get. Cause() Throwable init. Cause(Throwable) Throwable(String, Throwable) Throwable(Throwable) • try { } catch (IOException e) { throw new Sample. Exception("Other IOException", e); }

Accessing stack trace • catch (Exception cause) { Stack. Trace. Element elements[] = cause.

Accessing stack trace • catch (Exception cause) { Stack. Trace. Element elements[] = cause. get. Stack. Trace(); for (int i = 0, n = elements. length; i < n; i++) { System. err. println(elements[i]. get. File. Name() + ": " + elements[i]. get. Line. Number() + ">> " + elements[i]. get. Method. Name() + "()"); } }

Logging API • try { Handler handler = new File. Handler("Out. File. log"); Logger.

Logging API • try { Handler handler = new File. Handler("Out. File. log"); Logger. get. Logger(""). add. Handler(handler); } catch (IOException e) { Logger logger = Logger. get. Logger("package. name"); Stack. Trace. Element elements[] = e. get. Stack. Trace(); for (int i = 0; n = elements. length; i < n; i++) { logger. log(Level. WARNING, elements[i]. get. Method. Name());

Contents • • • Handling errors using exceptions Multi-threading I/O Setting program attributes Accessing

Contents • • • Handling errors using exceptions Multi-threading I/O Setting program attributes Accessing system resources

Thread • A thread — sometimes called an execution context or a lightweight process

Thread • A thread — sometimes called an execution context or a lightweight process — is a single sequential flow of control within a program • A thread is similar to a real process in that both have a single sequential flow of control. However, a thread is considered lightweight because it runs within the context of a full-blown program and takes advantage of the resources allocated for that program • As a sequential flow of control, a thread must carve out some resources within a running program. For example, a thread must have its own execution stack and program counter

A timer • import java. util. Timer; // Simple demo that uses java. util.

A timer • import java. util. Timer; // Simple demo that uses java. util. Timer to // schedule a task to execute once 5 seconds have passed import java. util. Timer. Task; public class Reminder { Timer timer; public Reminder(int seconds) { timer = new Timer(); timer. schedule(new Remind. Task(), seconds*1000); } class Remind. Task extends Timer. Task { public void run() { System. out. format("Time's up!%n"); timer. cancel(); //Terminate the timer thread } }

Steps of implementing timer • Implement a custom subclass of Timer. Task. The run

Steps of implementing timer • Implement a custom subclass of Timer. Task. The run method contains the code that performs the task. • Create a thread by instantiating the Timer class. • Instantiate the Timer. Task object. • Schedule the timer task for execution. • //Get the Date corresponding to 11: 00 pm today. Calendar calendar = Calendar. get. Instance(); calendar. set(Calendar. HOUR_OF_DAY, 23); calendar. set(Calendar. MINUTE, 1); calendar. set(Calendar. SECOND, 0); Date time = calendar. get. Time(); timer = new Timer(); timer. schedule(new Remind. Task(), time);

Stopping timer thread • Invoke cancel on the timer. You can do this from

Stopping timer thread • Invoke cancel on the timer. You can do this from anywhere in the program, such as from a timer task's run method. • Make the timer's thread a "daemon" by creating the timer like this: new Timer(true). If the only threads left in the program are daemon threads, the program exits. • After all the timer's scheduled tasks have finished executing, remove all references to the Timer object. Eventually, the timer's thread will terminate. • Invoke the System. exit method, which makes the entire program (and all its threads) exit.

 • public class Reminder. Beep {. . . public Reminder. Beep(int seconds) {

• public class Reminder. Beep {. . . public Reminder. Beep(int seconds) { toolkit = Toolkit. get. Default. Toolkit(); timer = new Timer(); timer. schedule(new Remind. Task(), seconds*1000); } class Remind. Task extends Timer. Task { public void run() { System. out. format("Time's up!%n"); toolkit. beep(); //timer. cancel(); //Not necessary because //we call System. exit(0); //Stops the AWT thread //(and everything else). } }. . . }

Periodic task • public class Annoying. Beep { Toolkit toolkit; Timer timer; public Annoying.

Periodic task • public class Annoying. Beep { Toolkit toolkit; Timer timer; public Annoying. Beep() { toolkit = Toolkit. get. Default. Toolkit(); timer = new Timer(); timer. schedule(new Remind. Task(), 0, //initial delay 1*1000); //subsequent rate } class Remind. Task extends Timer. Task { int num. Warning. Beeps = 3; public void run() { if (num. Warning. Beeps > 0) { toolkit. beep(); num. Warning. Beeps--; } System. exit(0); } } }

Implementing a thread • Subclassing Thread class and overriding run method • public class

Implementing a thread • Subclassing Thread class and overriding run method • public class Simple. Thread extends Thread { public Simple. Thread(String str) { super(str); } public void run() { for (int i = 0; i < 10; i++) { System. out. format("%d %s%n", i, get. Name()); try { sleep((long)(Math. random() * 1000)); } catch (Interrupted. Exception e) {} } System. out. format("DONE! %s%n", get. Name()); }

 • public class Two. Threads. Test { public static void main (String[] args)

• public class Two. Threads. Test { public static void main (String[] args) { new Simple. Thread("Jamaica"). start(); new Simple. Thread("Fiji"). start(); } }

 • Implement the Runnable interface and its run method and then create a

• Implement the Runnable interface and its run method and then create a thread with itself as the Thread's target. • public class Clock extends java. applet. Applet implements Runnable { private volatile Thread clock. Thread = null; public void start() { if (clock. Thread == null) { clock. Thread = new Thread(this, "Clock"); clock. Thread. start(); } } public void run() { Thread my. Thread = Thread. current. Thread(); while (clock. Thread == my. Thread) { repaint(); try { Thread. sleep(1000); } catch (Interrupted. Exception e){ } } } public void stop() { clock. Thread = null; }

Life cycle of a thread

Life cycle of a thread

Life cycle of a thread • A thread is started by its start() method

Life cycle of a thread • A thread is started by its start() method • A thread enters Not Runnable state when one of the following events occurs: – Its sleep method is invoked. – The thread calls the wait method to wait for a specific condition to be satisifed. – The thread is blocking on I/O • A thread should arrange for its own death by having a run method that terminates naturally • Thread. get. State() method returns Thread. State values that include: NEW, RUNNABLE, BLOCKED , WAITING, TIMED_WAITING, TERMINATED • The Thread. is. Alive() method returns true if the thread has been started and not stopped

Scheduling • The Java runtime environment supports a very simple, deterministic algorithm called fixedpriority

Scheduling • The Java runtime environment supports a very simple, deterministic algorithm called fixedpriority scheduling • This algorithm schedules threads on the basis of their priority relative to other Runnable threads • When a thread is created, it inherits priority from the thread that created it. • In addition, by using the set. Priority method, you can modify a thread's priority at any time after its creation. • Thread priorities are integers that range between MIN_PRIORITY and MAX_PRIORITY (constants defined in the Thread class).

Relinquishing the CPU • Writing CPU-intensive code can have negative repercussions on other threads

Relinquishing the CPU • Writing CPU-intensive code can have negative repercussions on other threads running in the same process. • In general, try to write well-behaved threads that voluntarily relinquish the CPU periodically and give other threads an opportunity to run. • A thread can voluntarily yield the CPU by calling the yield method, which gives other threads of the same priority a chance to run. If no equal-priority threads are Runnable, yield is ignored.

Synchronizing threads • public class Producer extends Thread { private Cubby. Hole cubbyhole; private

Synchronizing threads • public class Producer extends Thread { private Cubby. Hole cubbyhole; private int number; public Producer(Cubby. Hole c, int number) { cubbyhole = c; this. number = number; } public void run() { for (int i = 0; i < 10; i++) { cubbyhole. put(number, i); try { sleep((int)(Math. random() * 100)); } catch (Interrupted. Exception e) { } }

 • public class Consumer extends Thread { private Cubby. Hole cubbyhole; private int

• public class Consumer extends Thread { private Cubby. Hole cubbyhole; private int number; public Consumer(Cubby. Hole c, int number) { cubbyhole = c; this. number = number; } public void run() { int value = 0; for (int i = 0; i < 10; i++) { value = cubbyhole. get(number); } } }

Locking an object • public class Cubby. Hole { private int contents; private boolean

Locking an object • public class Cubby. Hole { private int contents; private boolean available = false; public synchronized int get(int who) { //Cubby. Hole locked by the Producer. . //Cubby. Hole unlocked by the Producer } public synchronized void put(int who, int value) { //Cubby. Hole locked by the Consumer. . //Cubby. Hole unlocked by the Consumer. }

Reentrant lock • The same thread can call a synchronized method on an object

Reentrant lock • The same thread can call a synchronized method on an object for which it already holds the lock, thereby reacquiring the lock • The Java runtime environment allows a thread to reacquire a lock because the locks are reentrant • Reentrant locks are important because they eliminate the possibility of a single thread having to wait for a lock that it already holds

notify and wait methods • public synchronized int get() { //Won't work! if (available

notify and wait methods • public synchronized int get() { //Won't work! if (available == true) { available = false; return contents; } } public synchronized void put(int value) { //Won't work! if (available == false) { available = true; contents = value; } }

 • public synchronized int get() { while (available == false) { try {

• public synchronized int get() { while (available == false) { try { //Wait for Producer to put value. wait(); } catch (Interrupted. Exception e) { } } available = false; notify. All(); //Notify Producer that value has been retrieved. return contents; } public synchronized void put(int value) { while (available == true) { try { //Wait for Consumer to get value. wait(); } catch (Interrupted. Exception e) { } } contents = value; available = true; . notify. All(); //Notify Consumer that value has been set

Running the consumer/producer • public class Producer. Consumer. Test { public static void main(String[]

Running the consumer/producer • public class Producer. Consumer. Test { public static void main(String[] args) { Cubby. Hole c = new Cubby. Hole(); Producer p = new Producer(c, 1); Consumer c = new Consumer(c, 1); p. start(); c. start(); } }

Explicit lock • An explicit lock is more flexible than using the synchronized keyword

Explicit lock • An explicit lock is more flexible than using the synchronized keyword because the lock can span a few statements in a method or multiple methods in addition to the scopes (block and method) supported by synchronized • To create an explicit lock, instantiate an implementation of the Lock interface, usually Reentrant. Lock. To grab the lock, invoke the lock method; to release the lock, invoke the unlock method. You should wrap the lock and unlock methods in a try/finally clause • To wait on an explicit lock, create a condition variable (an object that supports the Condition interface) using the Lock. new. Condition method. Condition variables provide the methods await — to wait for the condition to be true, and signal. All — to notify all waiting threads that the condition has occurred

 • import java. util. concurrent. locks. *; public class Cubby. Hole 2 {

• import java. util. concurrent. locks. *; public class Cubby. Hole 2 { private int contents; private boolean available = false; private Lock a. Lock = new Reentrant. Lock(); private Condition cond. Var = a. Lock. new. Condition(); public int get(int who) { a. Lock. lock(); try { while (available == false) { try { cond. Var. await(); } catch (Interrupted. Exception e) { } } available = false; cond. Var. signal. All(); } finally { a. Lock. unlock(); } return contents; }

public void put(int who, int value) { a. Lock. lock(); try { while (available

public void put(int who, int value) { a. Lock. lock(); try { while (available == true) { try { cond. Var. await(); } catch (Interrupted. Exception e) { } } contents = value; available = true; System. out. format("Producer %d put: %d%n", who, contents); cond. Var. signal. All(); } finally { a. Lock. unlock(); } }

Synchronized data structure • In your programs, you probably will want to take advantage

Synchronized data structure • In your programs, you probably will want to take advantage of the java. util. concurrent package's data structures that hide all the synchronization details

 • import java. util. concurrent. *; public class Producer 3 extends Thread {

• import java. util. concurrent. *; public class Producer 3 extends Thread { private Blocking. Queue cubbyhole; private int number; public Producer 3(Blocking. Queue c, int num) { cubbyhole = c; number = num; } public void run() { for (int i = 0; i < 10; i++) { try { cubbyhole. put(i); System. out. format("Producer #%d put: %d%n", number, i); sleep((int)(Math. random() * 100)); } catch (Interrupted. Exception e) { } } }

 • import java. util. concurrent. *; public class Producer. Consumer. Test 3 {

• import java. util. concurrent. *; public class Producer. Consumer. Test 3 { public static void main(String[] args) { Array. Blocking. Queue c = new Array. Blocking. Queue(1); Producer 3 p = new Producer 3(c, 1); Consumer 3 c = new Consumer 3(c, 1); p. start(); c. start(); } }

Thread pool • A thread pool is a managed collection of threads that are

Thread pool • A thread pool is a managed collection of threads that are available to perform tasks. Thread pools usually provide the following: – Improved performance when executing large numbers of tasks as a result of reduced per-task invocation overhead. – A way of bounding the resources, including threads, consumed when executing a collection of tasks • In addition, thread pools relieve you from having to manage the life cycle of threads. • They allow to take advantage of threading, but focus on the tasks that you want the threads to perform instead of thread mechanics

Thread pool • To use thread pools, instantiate an implementation of the Executor. Service

Thread pool • To use thread pools, instantiate an implementation of the Executor. Service interface and hand it a set of tasks. • The choices of configurable thread pool implementations are Thread. Pool. Executor and Scheduled. Thread. Pool. Executor. • Recommend using the more convenient factory methods of the Executors class listed in the following table. Factory Methods in the Executors Class new. Fixed. Thread. Pool(int) Creates a fixed-size thread pool. new. Cached. Thread. Pool Creates an unbounded thread pool with automatic thread reclamation. new. Single. Thread. Executor Creates a single background thread.

 • public class Worker. Thread implements Runnable { private int worker. Number; Worker.

• public class Worker. Thread implements Runnable { private int worker. Number; Worker. Thread(int number) { worker. Number = number; } public void run() { for (int i=0; i<=100; i+=20) { //Perform some work. . . System. out. format("Worker number: %d, percent complete: %d%n", worker. Number, i); try { Thread. sleep((int)(Math. random() * 1000)); } catch (Interrupted. Exception e) { } }

 • import java. util. concurrent. *; public class Thread. Pool. Test { public

• import java. util. concurrent. *; public class Thread. Pool. Test { public static void main(String[ ] args) { int num. Workers = Integer. parse. Int(args[0]); int thread. Pool. Size = Integer. parse. Int(args[1]); Executor. Service tpes = Executors. new. Fixed. Thread. Pool (thread. Pool. Size); Worker. Thread[ ] workers = new Worker. Thread[num. Workers]; for (int i = 0; i < num. Workers; i++) { workers[i] = new Worker. Thread(i); tpes. execute(workers[i]); } tpes. shutdown(); } }

 • import java. util. concurrent. *; public class Callable. Worker. Thread implements Callable<Integer>

• import java. util. concurrent. *; public class Callable. Worker. Thread implements Callable<Integer> { private int worker. Number; Callable. Worker. Thread(int number) { worker. Number = number; } public Integer call() { for (int i = 0; i <= 100; i += 20) { //Perform some work. . . System. out. format("Worker number: %d, percent complete: %d%n", worker. Number, i); try { Thread. sleep((int)(Math. random() * 1000)); } catch (Interrupted. Exception e) {} } return(worker. Number); } }

 • public class Thread. Pool. Test 2 { public static void main(String[] args)

• public class Thread. Pool. Test 2 { public static void main(String[] args) { int num. Workers = Integer. parse. Int(args[0]); Executor. Service tpes = Executors. new. Cached. Thread. Pool(); Callable. Worker. Thread workers[] = new Callable. Worker. Thread[num. Workers]; Future<Integer> futures[] = new Future[num. Workers]; for (int i = 0; i < num. Workers; i++) { workers[i] = new Callable. Worker. Thread(i); futures[i]=tpes. submit(workers[i]); } for (int i = 0; i < num. Workers; i++) { try { System. out. format("Ending worker: %d%n", futures[i]. get()); } catch (Exception e) {} }

Contents • • • Handling errors using exceptions Multi-threading I/O Setting program attributes Accessing

Contents • • • Handling errors using exceptions Multi-threading I/O Setting program attributes Accessing system resources

I/O streams

I/O streams

I/O algorithms Reading Writing 1. open a stream 2. while more information read information

I/O algorithms Reading Writing 1. open a stream 2. while more information read information 3. close the stream 1. open a stream 2. while more information write information 3. close the stream

Class hierarchies in java. io • The java. io package contains two independent hierarchies

Class hierarchies in java. io • The java. io package contains two independent hierarchies of classes: – one for reading / writing bytes – the other for reading / writing characters.

Character Streams • Subclasses of Reader and Writer has two categories: – those that

Character Streams • Subclasses of Reader and Writer has two categories: – those that read from or write to data sinks and – those that perform some sort of processing

Character Streams • Subclasses of Reader and Writer has two categories: – those that

Character Streams • Subclasses of Reader and Writer has two categories: – those that read from or write to data sinks and – those that perform some sort of processing

Byte streams • Input. Stream and Output. Stream provide the API and partial implementation

Byte streams • Input. Stream and Output. Stream provide the API and partial implementation for input streams (streams that read 8 -bit bytes) and output streams (streams that write 8 -bit bytes). • These streams are typically used to read and write binary data such as images and sounds. • Two of the byte stream classes, Object. Input. Stream and Object. Output. Stream, are used for object serialization

 • As with Reader and Writer, subclasses of Input. Stream and Output. Stream

• As with Reader and Writer, subclasses of Input. Stream and Output. Stream provide specialized I/O of two categories, : data sink streams (shaded), processing streams (unshaded)

 • As with Reader and Writer, subclasses of Input. Stream and Output. Stream

• As with Reader and Writer, subclasses of Input. Stream and Output. Stream provide specialized I/O of two categories, : data sink streams (shaded), processing streams (unshaded)

I/O super-classes • Reader and Input. Stream define similar APIs but for different data

I/O super-classes • Reader and Input. Stream define similar APIs but for different data types. For example, Reader contains these methods for reading characters and arrays of characters. – int read() – int read(char cbuf[], int offset, int length) • Input. Stream defines the same methods but for reading bytes and arrays of bytes: – int read() – int read(byte cbuf[], int offset, int length)

I/O super-classes • Writer and Output. Stream are similarly parallel. Writer defines these methods

I/O super-classes • Writer and Output. Stream are similarly parallel. Writer defines these methods for writing characters and arrays of characters: – int write(int c) – int write(char cbuf[], int offset, int length) • Output. Stream defines the same methods for bytes: – int write(int c) – int write(byte cbuf[], int offset, int length)

I/O streams • All of the streams — readers, writers, input streams, and output

I/O streams • All of the streams — readers, writers, input streams, and output streams — are automatically opened when created. • Close a stream by calling its close method. A program should close a stream as soon as it is done with it, in order to free up system resources.

Using the streams Memory Pipe Char. Array. Reader(Writer), Byte. Array. Input(Output)Stream String. Reader(Writer), String.

Using the streams Memory Pipe Char. Array. Reader(Writer), Byte. Array. Input(Output)Stream String. Reader(Writer), String. Buffer. Input. Stream Piped. Reader(Writer), Piped. Input(Output)Stream File Concatenate Serialize Conversion File. Reader(Writer), File. Input(Output)Stream Counting Lookahead Printing Buffering Filtering Conversion Line. Number. Reader(Input. Stream) Pushback. Reader(Input. Stream) Print. Writer(Stream) Buffered. Reader(Writer), Buffered. Input(Output)Stream Filter. Reader(Writer), Filter. Input(Output)Stream Input. Stream. Reader, Output. Stream. Writer Sequence. Input. Stream Object. Input(Output)Stream Data. Input(Output)Stream

File stream • import java. io. *; public class Copy { public static void

File stream • import java. io. *; public class Copy { public static void main(String[] args) throws IOException { File input. File = new File("farrago. txt"); File output. File = new File("outagain. txt"); File. Reader in = new File. Reader(input. File); File. Writer out = new File. Writer(output. File); int c; while ((c = in. read()) != -1) out. write(c); in. close(); out. close(); } } • File. Input. Stream in = new File. Input. Stream(input. File); File. Output. Stream out = new File. Output. Stream(output. File);

Use pipe stream • File. Reader words = new File. Reader("words. txt"); Reader rhyming.

Use pipe stream • File. Reader words = new File. Reader("words. txt"); Reader rhyming. Words = reverse(sort(reverse(words))); public static Reader reverse(Reader src) throws IOException { Buffered. Reader in = new Buffered. Reader(src); Piped. Writer pipe. Out = new Piped. Writer(); Piped. Reader pipe. In = new Piped. Reader(pipe. Out); Print. Writer out = new Print. Writer(pipe. Out); new Reverse. Thread(out, in). start(); return pipe. In; }

 • public class Reverse. Thread extends Thread { private Print. Writer out; private

• public class Reverse. Thread extends Thread { private Print. Writer out; private Buffered. Reader in; public Reverse. Thread(Print. Writer out, Buffered. Reader in) { this. out = out; this. in = in; } public void run() { if (out != null && in != null) { String input; while ((input = in. read. Line()) != null) { out. println(reverse. It(input)); out. flush(); } out. close(); } } private String reverse. It(String source) { … } }

Wrap a stream • Buffered. Reader in = new Buffered. Reader(source); . . .

Wrap a stream • Buffered. Reader in = new Buffered. Reader(source); . . . Print. Writer out = new Print. Writer(pipe. Out); • The program reads from the Buffered. Reader, which in turn reads from source. The program does this so that it can use Buffered. Reader's convenient read. Line method • The Piped. Writer is wrapped in a Print. Writer so that the program can use Print. Writer's convenient println method

Concatenate files • import java. io. *; public class Concatenate { public static void

Concatenate files • import java. io. *; public class Concatenate { public static void main(String[] args) throws IOException { List. Of. Files mylist = new List. Of. Files(args); Sequence. Input. Stream s = new Sequence. Input. Stream(mylist); int c; while ((c = s. read()) != -1) System. out. write(c); s. close(); } }

public class List. Of. Files implements Enumeration<File. Input. Stream> { private String[] list. Of.

public class List. Of. Files implements Enumeration<File. Input. Stream> { private String[] list. Of. Files; private int current = 0; public List. Of. Files(String[] list. Of. Files) { this. list. Of. Files = list. Of. Files; } public boolean has. More. Elements() { if (current < list. Of. Files. length) return true; else return false; } public File. Input. Stream next. Element() { File. Input. Stream in = null; if (!has. More. Elements()) throw new Exception("No more files. "); else { String next. Element = list. Of. Files[current]; current++; try { in = new File. Input. Stream(next. Element); }

Using filter streams Buffered. Reader d = new Buffered. Reader( new Input. Stream. Reader(System.

Using filter streams Buffered. Reader d = new Buffered. Reader( new Input. Stream. Reader(System. in)); String input; while ((input = d. read. Line()) != null) {. . . //do something interesting here }

Scanning • import java. io. *; import java. util. *; public class Scan. Far

Scanning • import java. io. *; import java. util. *; public class Scan. Far { public static void main(String[] args) throws IOException { Scanner s = new Scanner(new Buffered. Reader( new File. Reader("farrago. txt"))); while (s. has. Next()) { System. out. println(s. next()); } s. close(); } }

Formatting • public class Root { public static void main(String[] args) { int i

Formatting • public class Root { public static void main(String[] args) { int i = 2; double r = Math. sqrt(i); System. out. format("The square root of %d is %f. %n", i, r); } } Here is the output: The square root of 2 is 1. 414214.

Formatting • • • %d formats an integer value as a decimal value; %f

Formatting • • • %d formats an integer value as a decimal value; %f formats a floating point value as a decimal value; %n outputs a locale-specific line terminator. %x formats an integer as a hexadecimal value; %s formats any value as a string; %t. B formats an integer as a locale-specific month name.

Object serialization • Remote Method Invocation (RMI)-communication between objects via sockets • Lightweight persistence--the

Object serialization • Remote Method Invocation (RMI)-communication between objects via sockets • Lightweight persistence--the archival of an object for use in a later invocation of the same program

Serializing objects • File. Output. Stream out = new File. Output. Stream("the. Time"); Object.

Serializing objects • File. Output. Stream out = new File. Output. Stream("the. Time"); Object. Output. Stream s = new Object. Output. Stream(out); s. write. Object("Today"); s. write. Object(new Date()); s. flush(); • File. Input. Stream in = new File. Input. Stream("the. Time"); Object. Input. Stream s = new Object. Input. Stream(in); String today = (String) s. read. Object(); Date date = (Date) s. read. Object();

Serializable objects • public class My. Serializable. Class implements Serializable {. . . }

Serializable objects • public class My. Serializable. Class implements Serializable {. . . } • serialization of instances of this class are handled by the default. Write. Object method of Object. Output. Stream – Class of the object – Class signature – Values of all non-transient and non-static members, including members that refer to other objects • deserialize any instance of the class with the default. Read. Object method in Object. Input. Stream

New I/O package • some programmers of high-performance applications will need the java. nio.

New I/O package • some programmers of high-performance applications will need the java. nio. * packages. • These packages provide APIs for scalable I/O, fast buffered byte and character I/O, and character set conversion • The New I/O APIs are designed for performance tuning — not day-to-day I/O programming

Contents • • • Handling errors using exceptions Multi-threading I/O Setting program attributes Accessing

Contents • • • Handling errors using exceptions Multi-threading I/O Setting program attributes Accessing system resources

Set program attributes • Java programs run within an environment that contains system attributes:

Set program attributes • Java programs run within an environment that contains system attributes: a host machine, a user, a current directory, and an operating system. • A Java program also can set up its own configurable attributes, called program attributes. • Program attributes allow the user to configure various startup options, preferred window size, and so on for the program. • System attributes are maintained by the System class. Java programs can set their own set of program attributes through three mechanisms: – properties, – command-line arguments, and – applet parameters

Properties • A property defines attributes on a persistent basis. • An attribute has

Properties • A property defines attributes on a persistent basis. • An attribute has two parts: a name and a value. For example, “os. name” contains the name of the current operating system such as “Linux” • The Properties class in the java. util package manages a set of key/value pairs. Each Properties key contains the name of a system attribute, and its corresponding Properties value is the current value of that attribute • The System class uses a Properties object for managing system properties. Any Java program can use a Properties object to manage its program attributes

Life cycle of a program’s properties

Life cycle of a program’s properties

Contents • • • Handling errors using exceptions Multi-threading I/O Setting program attributes Accessing

Contents • • • Handling errors using exceptions Multi-threading I/O Setting program attributes Accessing system resources

Access system resources • The Java platform lets your program access system resources through

Access system resources • The Java platform lets your program access system resources through a (relatively) system-independent API implemented by the System class and through a systemdependent API implemented by the Runtime class

Use the system class • System. out • System. get. Property(argument); • class User.

Use the system class • System. out • System. get. Property(argument); • class User. Name. Test { public static void main(String[] args) { String name; name = System. get. Property("user. name"); System. out. println(name); }

The standard I/O streams • Standard input--referenced by System. in – Used for program

The standard I/O streams • Standard input--referenced by System. in – Used for program input, typically reads input entered by the user. • Standard output--referenced by System. out – Used for program output, typically displays information to the user. • Standard error--referenced by System. err – Used to display error messages to the user

System properties • • • • file. separator File separator (for example, "/") java.

System properties • • • • file. separator File separator (for example, "/") java. class. path Java class-path java. class. version Java class version number java. home Java installation directory java. vendor Java vendor-specific string java. vendor. url Java vendor URL java. version Java version number line. separator Line separator os. arch Operating system architecture os. name Operating system name os. version Operating system version path. separator Path separator (for example, ": ") user. dir User's current working directory user. home User home directory user. name User account name

Get / set system properties • System. get. Property("path. separator"); • import java. io.

Get / set system properties • System. get. Property("path. separator"); • import java. io. File. Input. Stream; import java. util. Properties; public class Properties. Test { public static void main(String[] args) throws Exception { // set up new properties object // from file "my. Properties. txt" File. Input. Stream prop. File = new File. Input. Stream( "my. Properties. txt"); Properties p = new Properties(System. get. Properties()); p. load(prop. File); // set the system properties System. set. Properties(p); // display new properties System. get. Properties(). list(System. out); }

Forcing finalization and GC • Before an object is garbage collected, the Java runtime

Forcing finalization and GC • Before an object is garbage collected, the Java runtime system gives the object a chance to clean up after itself. This step is known as finalization and is achieved through a call to the object's finalize method. You can force object finalization to occur by calling System's run. Finalization method. • System. run. Finalization(); This method calls the finalize methods on all objects that are waiting to be garbage collected. • You can ask the garbage collector to run at any time by calling System's gc method: System. gc();

Provide own security manager • The security manager is an application-wide object that determines

Provide own security manager • The security manager is an application-wide object that determines whether potentially threatening operations should be allowed. • The classes in the Java packages cooperate with the security manager by asking the application's security manager for permission to perform certain operations

Security manager • Security. Manager appsm = System. get. Security. Manager(); • Security. Manager

Security manager • Security. Manager appsm = System. get. Security. Manager(); • Security. Manager security = System. get. Security. Manager(); if (security != null) { security. check. Exit(status); }. . . // code continues here if checked. Exit() returns

Write a security manager • class Password. Security. Manager extends Security. Manager {. .

Write a security manager • class Password. Security. Manager extends Security. Manager {. . . } • Password. Security. Manager(String password) { super(); this. password = password; } • private boolean access. OK() { int c; Data. Input. Stream dis = new Data. Input. Stream(System. in); String response; response = dis. read. Line(); if (response. equals(password)) return true; else return false; } • public void check. Read(String filename) { if (!access. OK()) throw new Security. Exception("No Way!"); } • public void check. Write(String filename) { if (!access. OK()) throw new Security. Exception("Not Even!");

Install a security manager • try { System. set. Security. Manager( new Password. Security.

Install a security manager • try { System. set. Security. Manager( new Password. Security. Manager(“some password")); } catch (Security. Exception se) { System. out. println("Security. Manager already set!"); }

Override methods of security manager • sockets check. Accept(String host, int port) check. Connect(String

Override methods of security manager • sockets check. Accept(String host, int port) check. Connect(String host, int port) check. Listen(int port) threads check. Access(Thread thread) class loader check. Create. Class. Loader() file system check. Delete(String filename) check. Link(String library) check. Read(String filename) check. Write(String filename) system commands check. Exec(String command) interpreter check. Exit(int status) package check. Package. Access(String package. Name) check. Package. Definition(String package. Name) properties check. Properties. Access()

Other system methods • System. exit(-1); • System. current. Time. Millis(); • System. arraycopy(

Other system methods • System. exit(-1); • System. current. Time. Millis(); • System. arraycopy( Object source, int src. Index, Object dest, int dest. Index, int length );

Runtime object • Runtime objects provide two services. – First, they communicate with the

Runtime object • Runtime objects provide two services. – First, they communicate with the components of the runtime environment--getting information and invoking functions. – Second, Runtime objects are also the interface to systemdependent capabilities