Unit I Java Basics Java as object-oriented programming language Java is an object-oriented programming language that can produce software for various platforms It is secure, portable and platform independent Lets programmers write once, run anywhere (WORA) It can be used to create stand-alone applications, web apps, programs for consumer devices like mobile phones, games etc Java derives its syntax from C and object-oriented features from C++ History Developed by Sun Microsystems and released in 1995, now acquired by Oracle Originally called Oak by James Gosling, one of the inventors of the Java Language Initial objective was to develop a platform-independent language that can be used to create software for embedding in consumer electronic devices like remote controls and microwave ovens This portability of Java was something the world wide web very much needed, and that's what caused the focus of Java to switch from consumer electronics to internet programming Features High level Simple - removes a number of complex features that existed in C like pointer manipulation and operator overloading Object-oriented Platform independent Network-savvy Robust - checks the code during both compilation and interpretation Secure - provides a controlled execution environment with several layers of security Architecture neutral Portable High-performance Multi-threaded Java C++ Developed at Sun Microsystems Developed at Bell Labs Released 1995 Released 1985 Platform independent Platform dependent Portable, same code can run on any OS Not portable Both compiled and interpreted Compiled Java Does not support pointers, mainly for security reasons Object-oriented only C++ Supports pointers Both object-oriented and procedural Uses System class for I/O Uses cin and cout Higher level Closer to hardware Java architecture Source code is compiled to bytecode using JDK, which is interpreted and executed by the JVM JVM - Java Virtual Machine Very important part of both JDK and JVM Responsible for executing the program line by line Makes platform independence possible Also known as interpreter JRE - Java Runtime Environment (Java RTE) Provides the minimum requirements for executing a Java application Consists of the Java Virtual Machine (JVM), library classes and supporting files JDK - Java Development Kit A software development environment used for developing Java applications and applets It includes the Java Runtime Environment (JRE), an interpreter/loader (Java), a compiler (javac), an archiver (jar), a documentation generator (javadoc) and other tools needed in Java development An applet is a special kind of Java program that is designed to be transmitted over the internet and automatically executed by a Java-compatible web browser. An applet is downloaded on demand, without further interaction with the user. Servlets also exist, small programs that execute on the server. Use of bytecode ensures portability and confinement of code to JVM execution environment ensures security. Syntax and rules //Example.java - the name of the main class should match the name of the file that holds the program class Example { //every program begins with a call to main(). public static void main(String args[]) { int num, b=100; num = 100; System.out.println("This is num: " + num); //num is converted to string and concatenated num = num * 2; System.out.print("The value of num * 2 is "); //print() does not add newline in the end System.out.println(num); } } //compile using "javac Example.java" to get "Example.class" and then execute using "java Example" /* public - access modifier static - allows class method to be called without creating object void - return type main - name of method String args[] - declares array of strings named args, used to store command-line arguments */ Java tokens Primitive data types byte, short, int, long (all are signed integers of lengths 8/16/32/64 bits) float, double (32 and 64 bits) char (16 bit Unicode unlike 8 bits in C/C++; treated as an integer) ch1=88; ch1='X' //both these statements are equivalent boolean (true, false) String is not a type but an object Literals - constant values Variables - used via identifiers; identifiers may be any sequence of case-sensitive alphabets, numbers, dollar signs and underscores, they cannot begin with a number Scope and lifetime of variables A block (enclosed in curly braces) defines the scope of a variable. Variables inside a scope are not visible or accessible outside. Nested scope can access variables of the enclosing scope, but not vice-versa. Unlike other languages where global and local are the major scopes, Java's major scopes are class and method. Global variables are not possible directly but can be defined inside a class using public static type name = val . Parameters of a method are also included inside it's scope. The lifetime of a variable is confined to its scope. Variables are created when their scope is entered, and destroyed when their scope is left. A variable inside a nested scope cannot shadow (have the same name as) a variable of the enclosing scope. Operators Arithmetic Bitwise (java stores integers as signed values, negative numbers are encoded using two's complement where bits are flipped and 1 is added to the result; 1 is added to solve the problem of existence of negative zero) ~ NOT & AND | OR ^ XOR >> Shift right (leftmost bits are shifted and get lost, automatically fills the high-order bit with its previous contents each time a shift occurs to preserve sign - this is called sign extension) >>> Shift right zero fill (unsigned shift right, fills zero instead of previous contents) << Shift left (rightmost bits are shifted and get lost, empty space is filled with zero) Relational - > < >= <= == != Boolean logic - & | ^ || && ! Only operates on boolean operands &&/|| are short-circuit (conditional) AND/OR operators, second operand is not evaluated if first one is false/true. Assignment = Ternary a ? b : c Standard/library classes - provide support for I/O, string handling, networking etc - for example System Control structures/statements Three types - selection (if and switch), iteration (for, while and do-while) and jump (break, continue, return) if(num < 100) { b=50; } else { b=0; } if(num < 100) b=50; else if(num > 200) b=10; else b=0; //=============== switch(expression) { //expression can be int or string case value1: //statements break; case value2: //statements break; case valueN: //statements break; default: //statements } switch(expression) { //multiple cases can be used with the same statements like this case value1: case value2: case value3: //statements break; case valueN: //statements break; default: //statements } //=============== for(int i=0; i<=50; i++) { doSomething(); } for(int i=0; i<=50; i++) System.out.println('Hola'); for(int a=1, b=4; a<b; a++, b--) System.out.println('Hola'); for(;!done;) something(); //infinite conditional loop for(;;) something(); //infinite loop for(int x: nums) sum += x; //for int x in nums, changing x inside loop does not affect nums //=============== while(condition) { doSomething; } //=============== do { //executes body once before checking condition //body } while(condition); //=============== first: { second: { third: { //labelled code blocks if(t) break second; } } //execution resumes here, after the end of second } //=============== //continue can also specify a label to indicate which loop to continue outer: for (int i=0; i<10; i++) { for(int j=0; j<10; j++) { if(j > i) { System.out.println(); continue outer; } System.out.print(" " + (i * j)); } } //=============== switch can only test for equality; if can evaluate any expression No two switch cases can have identical values switch statements can be nested switch is more efficient than if-elses return statement terminates execution of method and returns control to caller b = (byte) a; //type casting Java sometimes does type casting/promotion/widening etc automatically causing unexpected behaviour. For example if two integers of different sizes are used in an expression, java promotes the smaller one to the larger one's type. Or if the result of an expression is bigger than it's operands, all operands are promoted to a larger size. Arrays A group of like-typed variables that are referred to by a common name May have one or more dimensions Specific elements are accessed by their indices array1.length int month_days[]; month_days = new int[12]; //new allocates memory dynamically (at runtime), all elements are automatically initialized to zero //OR int month_days[] = new int[12]; //OR int month_days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; System.out.println(month_days[3]); int twoD[][] = new int[4][5]; //OR (irregular multidimensional array) int twoD[][] = new int[4][]; twoD[0] = new int[5]; twoD[1] = new int[7]; twoD[2] = new int[9]; twoD[3] = new int[5]; //OR double m[][] = { {0, 1, 2, 3}, {03, 13, 23, 33}, {10, 11, 12, 13}, {101, 11, 12, 31}, }; //int[] a1 is same as int a1[] Introducing Classes Class is a template for an object, and an object is an instance of a class Class = instance variables + methods Provides encapsulation class Box { double height; double width; double depth; double volume() { return height*width*depth; } void setDim(double a, double b, double depth) { height = a; width = b; this.depth = depth; } Box(double a, double b, double c) { //constructor height = a; width = b; depth = c; } protected void finalize() { //kind of a destructor, runs on garbage collection, not when object goes out of scope like C++ } } class BoxDemo { public static void main(String args[]) { Box mybox = new Box(1, 2, 3); Box b2 = mybox; //b2 points to the same object now mybox.setDim(3, 6, 9); System.out.println("Volume is " + mybox.volume()); mybox = null; //b2 still points to the same object } } Methods can be overloaded by varying the number and/or type of arguments. It's one of the ways that Java supports polymorphism. Constructors can also be overloaded. Objects can also be used as parameters to methods. This is often used to define constructors that can create a copy of an existing object. Java does not provide a default copy constructor like C++. Java default constructor initializes member data variable to default values (numeric values are initialized as 0, booleans are initialized as false and references are initialized as null). Object creation can be restricted by defining a private constructor. Primitive type parameters are passed using call-by-value. Objects parameters are passed using call-by-reference. A method can return any type of data, including an object. Java supports recursion. this keyword - used inside method to refer to the invoking object, useful if the method scope defines a variable with same name as one in the object scope. Garbage collection - Java handles deallocation automatically. When no references to an object exist, that object is assumed to be no longer needed, and the memory occupied by the object can be reclaimed. There is no explicit need to destroy objects as in C++ (delete keyword). Method access modifiers public - can be accessed by anyone. private - can be accessed by other class members only. Objects of the same class can access each other's private data. protected - can be accessed within the package and outside the package through child classes. When no access modifier is used, then by default the member of a class is public within its own package, but cannot be accessed outside of its package. A non-nested class has only two possible access levels: default and public. When a class is declared as public, it is accessible by any other code. If a class has default access, then it can only be accessed by other code within its same package. When a class is public, it must be the only public class declared in the file, and the file must have the same name as the class. Static (variable, method, block) When a class member (variable or method) is declared static, it can be accessed before any objects of its class are created, and without reference to any object. All instances of a class share the same static variables. If you need to do computation in order to initialize your static variables, you can declare a static block that gets executed exactly once, when the class is first loaded. Methods declared as static have some restrictions they can only directly call other static methods they can only directly access static data they cannot refer to this or super in any way final keyword - used to make classes, attributes/variables or methods constant/nonchangeable (impossible to inherit or override). final double PI = 3.14; - final variables cannot be edited, they are constant. final void someMethod() {.. - final methods cannot be overridden. final class A {.. - final classes cannot be inherited. String is a final class. It is illegal to declare a class as both abstract and final since an abstract class is incomplete by itself and relies upon its subclasses to provide complete implementations. Wrapper classes Used to convert primitive types to objects Integer, Short, Byte, Long, Float, Double, Character, Boolean Integer i = new Integer (17); or Integer i = 17; Provides methods for comparison, type conversion, based conversion etc To extract primitive value, use int iValue = i.intValue(); or int iValue = i; int i = Integer.parseInt(str); String str = Integer.toString(i); Primitive types cannot be null but wrapper classes can be String class and methods Strings are immutable They are objects that hold an array of characters String variables are references to String objects (memory addresses) + is used to concatenate strings, it automatically converts other data types to String Can be initialized using string literal, char array, byte array etc. String str = new String("blah"); String str = new String(char[]); If new operator is not used and another string with same value already exists, a reference will be created instead of a separate string Return value types and string methods boolean equals(secondStr) - compares contents unlike == which compares memory addresses boolean contains(secondStr) boolean startsWith(secondStr) boolean endsWith(secondStr) boolean isEmpty() char charAt(someInt) int indexOf(someChar) int length() String valueOf(anyDataType) String substring (i, k) - copies characters from index i to k-1 String substring (i) - copies characters from index i to end String concat(anyDataType) String toUpperCase() String toLowerCase() StringBuilder Used to create mutable strings Provides methods for appending, inserting and deleting characters Constructors empty - creates an empty buffer with initial capacity of 16 String str int capacity Methods length() capacity() append(anyType) insert(int index, String str) reverse() replace(int start, int end, String str) delete(int start, int end) StringBuffer - it is a thread safe implementation of StringBuilder Unit II Inheritance Parent and child classes are called superclass and subclass respectively. class B extends A {} A reference variable of a superclass can be assigned a reference to any subclass derived from that superclass. However it cannot be used to access members of the subclass that are not a part of the superclass. Dynamic method dispatch (runtime polymorphism) - when an overridden method is called through a superclass reference, Java determines which version of that method to execute based upon the type of the object being referred. Types - single, multilevel, hierarchical, hybrid. Multiple inheritance is not supported but can be achieved through interfaces. Super keyword - used by subclass to refer to its immediate superclass super(args); can be used as the first statement inside a subclass constructor to call the superclass' constructor eliminates redundancy can be used if superclass data members are private super.member can be used to access variables or methods, useful if subclass has members with same names Constructors are called in order of derivation, from superclass(es) to subclass(es). Method overriding - Occurs only when the names and the type signatures of the two methods are identical, otherwise the methods are overloaded. Superclass methods are hidden but they still exist and can be accessed using super . Covariant return type - return type of an overriding method - allows a subclass method to return a more specific type than the return type of the overridden method in the superclass. Methods can be overridden by changing return type. Abstract class used to define a superclass that declares the structure of a given abstraction without providing a complete implementation Abstract methods have no body and it is mandatory for subclasses to override them. abstract void callme(); Any class that contains one or more abstract methods must also be declared abstract. abstract class A{.. There can be no objects of an abstract class. You cannot declare abstract constructors, or abstract static methods. Any subclass of an abstract class must either implement all of the abstract methods in the superclass, or be declared abstract itself. Abstract classes can include concrete methods too. Although abstract classes cannot be used to instantiate objects, they can be used to create object references, because Java’s approach to run-time polymorphism is implemented through the use of superclass references. absClass obj; //legal absClass obj = new absClass(); //illegal Interfaces and Packages Creating and implementing an interface Using the keyword interface, you can fully abstract a class' interface from its implementation. Using interface, you can specify a set of methods that can be implemented by one or more classes. But the interface, itself, does not actually define any implementation. Unlike abstract classes, a class can implement more than one interface. To implement an interface, a class must create the complete set of methods defined by the interface. However, each class is free to determine the details of its own implementation. Interfaces add most of the functionality that is required for many applications that would normally resort to using multiple inheritance in a language such as C++. When no access modifier is included, then default access results, and the interface is only available to other members of the package in which it is declared. When it is declared as public, the interface can be used by any other code. In this case, the interface must be the only public interface declared in the file, and the file must have the same name as the interface. An interface can be declared a member of a class or another interface. A nested interface can be declared as public, private, or protected. When used outside its enclosing score, a nested interface should be qualified using its parent class/interface name and dot operator. Variables can be declared inside of interface declarations. They are implicitly final and static, meaning they cannot be changed by the implementing class. They must also be initialized. All methods and variables are implicitly public. interface Callback { void callback(int param); } class Client [extends blah] implements Callback {.. class Client [extends blah] implements Callback, B, C, D {.. The methods that implement an interface must be declared public. Also, the type signature of the implementing method must match exactly the type signature specified in the interface definition. You can declare variables as object references that use an interface rather than a class type. The method to be executed is looked up dynamically at run time, allowing classes to be created later than the code which calls methods on them (runtime polymorphism). An interface reference variable has knowledge only of the methods declared by its interface declaration. If a class includes an interface but does not fully implement the methods defined by that interface, then that class must be declared as abstract. One interface can inherit another by use of the keyword extends. Abstract Class Interface Faster Slower An abstract class can inherit a class and An interface can inherit multiple multiple interfaces. interfaces but not a class. Abstract class methods can have access Everything defined inside the interface modifiers. is implicitly public. Does not support multiple inheritance. Supports multiple inheritance. They can contain both abstract and They can contain abstract methods concrete methods. only. One subclass can inherit only one A class can implement more than one superclass. interface. Can be extended using keyword Can be implemented using keyword extends. implements. Declared using abstract keyword. Declared using interface keyword. Packages Packages are containers for classes. They are used to keep the class name space compartmentalized. The package is both a naming and a visibility control mechanism. To create a package, include a package command as the first statement in a Java source file. Any classes declared within that file will belong to the specified package. package pkgName; If you omit the package statement, the class names are put into the default package, which has no name. Java uses file system directories to store packages. For example, the .class files for any classes you declare to be part of MyPackage must be stored in a directory called MyPackage. More than one file can include the same package statement. Package hierarchy - package java.awt.image; , stored in java\awt\image Importing a package import statements occur immediately following the package statement (if it exists) and before any class definitions. Used to bring certain classes, or entire packages, into visibility. Once imported, a class can be referred to directly, using only its name. import java.util.Date; import java.io.*; import java.util.*; class MyDate extends Date {} == class MyDate extends java.util.Date {} When a package is imported, only those items within the package declared as public will be available to non-subclasses in the importing code. Exception Handling Throwable class -> Error, Exception. Error is critical and terminates program, exception can be handled. Exception class An exception is a runtime error, an abnormal condition that arises in a code sequence at run time. When an exceptional condition arises, an object representing that exception is created and thrown in the method that caused the error. It contains information about the exception such as the name and description of the exception and state of the program when the exception occurred. That method may choose to handle the exception itself, or pass it on. It is mandatory to either catch all checked exceptions or declare them in the throws clause, otherwise a compile-time error will result. Built-in and user-defined exceptions Built-in exceptions are the exceptions that are available in Java core libraries. They are raised implicitly by system because of illegal execution of program. User-defined exceptions are raised by the programmer. Checked and unchecked exceptions Checked exceptions Exceptions that the Java compiler requires us to handle. They are caused by exceptional situations beyond the programmer's control. Examples: FileNotFoundException , ClassNotFoundException , IllegalAccessException , NoSuchMethodException Unchecked exceptions Compiler does not check to see if a method handles or throws these exceptions. They are caused by flaws in the code logic. Classes that extend RuntimeException come under this category. Examples: IllegalArgumentException , NegativeArraySizeException , NullPointerException , ArrayIndexOutOfBoundsException , ArithmeticException . Any exception that is not caught by your program will ultimately be processed by the default handler. The default handler displays a string describing the exception, prints a stack trace from the point at which the exception occurred, and terminates the program. Use of try, catch, throw, throws, finally try Encloses the code that you want to monitor. Try statements can be nested. If an inner try statement does not have a catch handler for a particular exception, the next try statement's catch handlers are inspected for a match. This continues until one of the catch statements succeeds, or until all of the nested try statements are exhausted. If no catch statement matches, then the Java run-time system will handle the exception. Each try statement requires at least one catch or finally clause. catch Specifies the exception type that you wish to catch. There can be multiple catch clauses. catch(Exception e) is a generic catch statement often used in the end. finally Executed after a try/catch block has completed and before the code following the try/catch block. The finally block will execute whether or not an exception is thrown. If an exception is thrown, the finally block will execute even if no catch statement matches the exception. Finally block can be used to put cleanup code such as closing a file, closing connection etc. throw Used to throw an exception explicitly. throw new ArithmeticException(); The flow of execution stops immediately after the throw statement, any subsequent statements are not executed. throws Lists the types of exceptions that a method might throw. void calculate() throws IOException,SQLexception {.. It is an alternative to try/catch error handling. Error is propagated to caller instead of being handled by method. throw Used to explicitly throw an exception. throw exceptionobject throws Used to declare an exception. type method() throws exception-list {//body} Followed by an instance. Followed by a class. Used within the method. Used with the method signature. You cannot throw multiple exceptions. You can declare multiple exceptions. try { //normal program code if(t) throw SomeException; } catch(ArithmeticException e) { //exception handling code } catch(ArrayIndexOutOfBoundsException e) { //exception handling code } catch(Exception e) { //exception handling code } finally { //something } class MyException extends Exception { public String toString() { return "MyException: Invalid age."; } }