final unit 1

150
History of Java and Tour of JDK Java is an object-oriented programming language developed by Sun Microsystems, and modeled on C++, the Java language was designed to be small, simple, and portable across platforms and operating systems, both at the source and at the binary level, which means that Java programs (applets and applications) can run on any machine that has the Java virtual machine installed One might be surprised to learn that Java did not come into being because of Internet or World Wide Web (WWW), although it was WWW which propelled into java what it is as a language today and a de-facto standard for Server Side Softwares. Because of the similarities between C++ and Java, it is tempting to think of Java as the “Internet version of C++”, but it would be a big mistake since Java has practical and philosophical difference with C++. The history of java goes back to 1991, when a group of Sun Engineers led by Mr. Patrick Naughton and James Gosling wanted to design a small computer language that was to be used for consumer and electronic devices like Remote Controls, TV Switchboxes etc. Now since these devices were manufactured by different manufacturers who may choose different CPUs (Central Processing Units), the program should not be tied down to any single architecture. The project was code named “Green”. The languages was then called as Oak and since Oak was already an existing computer languages, it was code named as JAVA. But unfortunately, Sun did not get the project for which they were bidding and it was in 1994 with the advent of the WWW and browsers, java was propelled back in to the main stream. The JAVA as a language was reveled to the world in the Sun world 1995 conference and from there onwards different versions have come out with all the latest technologies being incorporated. The different versions are being dealt with separately in the coming modules. Java was basically invented as a platform independent software to be run on various electronic devices like remote controls, micro-wave ovens etc. The emphasis was on platform independence. Platform independence-that is, the ability of a program to move easily from one computer system to another-is one of the most significant advantages that Java has over other programming languages, particularly if your software needs to run on many different platforms. If you're writing software for the World Wide Web, being able to run the same program on many different systems is crucial to that program's success. It was with the increasing popularity of the Internet, java became as a language for the internet which lays emphasis on the client-server programming. Java achieves this platform independence by breaking up the process of compilation and interpretation in to two individual steps. We have two separate executable files for this purpose called the Compiler and the Interpreter. In the earlier programming languages, any code written was compiled and immediately interpreted to the underlying operating system machine standard and hence if the same program was taken to another machine having a different operating system, it would not work.

Upload: parthabhi

Post on 02-Jan-2016

25 views

Category:

Documents


2 download

DESCRIPTION

FINAL

TRANSCRIPT

Page 1: Final Unit 1

History of Java and Tour of JDK Java is an object-oriented programming language developed by Sun Microsystems, and modeled on C++, the Java language was designed to be small, simple, and portable across platforms and operating systems, both at the source and at the binary level, which means that Java programs (applets and applications) can run on any machine that has the Java virtual machine installed One might be surprised to learn that Java did not come into being because of Internet or World Wide Web (WWW), although it was WWW which propelled into java what it is as a language today and a de-facto standard for Server Side Softwares. Because of the similarities between C++ and Java, it is tempting to think of Java as the “Internet version of C++”, but it would be a big mistake since Java has practical and philosophical difference with C++. The history of java goes back to 1991, when a group of Sun Engineers led by Mr. Patrick Naughton and James Gosling wanted to design a small computer language that was to be used for consumer and electronic devices like Remote Controls, TV Switchboxes etc. Now since these devices were manufactured by different manufacturers who may choose different CPUs (Central Processing Units), the program should not be tied down to any single architecture. The project was code named “Green”. The languages was then called as Oak and since Oak was already an existing computer languages, it was code named as JAVA. But unfortunately, Sun did not get the project for which they were bidding and it was in 1994 with the advent of the WWW and browsers, java was propelled back in to the main stream. The JAVA as a language was reveled to the world in the Sun world 1995 conference and from there onwards different versions have come out with all the latest technologies being incorporated. The different versions are being dealt with separately in the coming modules. Java was basically invented as a platform independent software to be run on various electronic devices like remote controls, micro-wave ovens etc. The emphasis was on platform independence. Platform independence-that is, the ability of a program to move easily from one computer system to another-is one of the most significant advantages that Java has over other programming languages, particularly if your software needs to run on many different platforms. If you're writing software for the World Wide Web, being able to run the same program on many different systems is crucial to that program's success. It was with the increasing popularity of the Internet, java became as a language for the internet which lays emphasis on the client-server programming. Java achieves this platform independence by breaking up the process of compilation and interpretation in to two individual steps. We have two separate executable files for this purpose called the Compiler and the Interpreter. In the earlier programming languages, any code written was compiled and immediately interpreted to the underlying operating system machine standard and hence if the same program was taken to another machine having a different operating system, it would not work.

Page 2: Final Unit 1

In Java, after compilation a class file is generated which is also called as byte code file and this class file is then interpreted as per the underlying machine standard. If we take this class file from one machine to another, it would still run, because interpretation is done as per that machine’s operating system. The Java compiler takes your Java program and, instead of generating machine codes from your source files, it generates bytecodes. Bytecodes are instructions that look a lot like machine code, but are not specific to any one processor. To execute a Java program, you run a program called a Bytecode interpreter, which in turn reads the bytecodes and executes your Java program. The Java Bytecode interpreter is often also called the Java virtual machine or the Java runtime Java bytecodes are a special set of machine instructions that are not specific to any one processor or computer system. A platform-specific Bytecode interpreter executes the Java bytecodes For running java programs, we would require software called as Java Development Kit, which can be downloaded from www.java.sun.com site. The earlier version of JDK was 1.0 and the other major versions were 1.1, 1.2 and the present version 1.3. Many authors and books also call JDK 1.3 as Java 3 and this is specifically stated to ensure that there is no confusion. We will be studying on Java Development Kit 1.3 and all the codes and error messages are of this version. Please note that the description of error messages differs from version to version. Once we download the software and install the same on the machine, the directory structure would like this and the important directories and files are explained herewith.

Name of the Folder Description

bin

Contains all the executable files which is required to run the java programs like java.exe, javac.exe

demo

Contains some demo applets and applications along with source codes.

jre

Contains the run-time environment and officially called as the Java Runtime Environment

lib

Contains the library files that support the executable and UI development.

src.jar file

archive that contains the class library source ode (a collection of files with .java extension)

Uninst.isu file

The un-installation file

Page 3: Final Unit 1

Tools of JDK After having successfully installed the JDK, we will quickly go through the various tools which will be required for execution of the java programs. Now for executing our tools, we would first require to set the path in the autoexec.bat directory or we can individually create a batch file and run the same before executing java codes. We need to insert the following line in the autoexec.bat file or in the user defined batch file and the same is set path= c:\jdk1.3\bin where jdk1.3 is the directory name (default directory in which u have your jdk installed) Once we have executed the batch file, to ensure that our jdk is properly installed, we just need to just type javac on the dos prompt and it would give us a list of options. (Incase our jdk is not properly installed or the path is not properly given then it would give us a bad command output)

Name of the Executable Description

javac Compiler

java Interpreter

appletviewer Applet viewer

javadoc Documentation generator

The first executable used would obviously be javac which would generate a class file from the source code file. We can see what the various options of javac are by just calling javac on the dos prompt. To compile a particular source we will have to say javac Test.java wherein Test.java is the source code file name. (Note: All java files should end with the .java extension). The java executable is for interpreting the .class file generated from the earlier compiler option. Not interpreting a class file, we do not need to give the .java extension and it would simply be java Test, wherein Test is the name of the class file automatically generated. The appletviewer is a mini browser inbuilt into JDK specifically for running the java Applets. (Java Applets are not a part of the certification exam and is not explained hence forth). The javadoc is a document generator by which automatic documentation will be generated from the java codes based on special comments given in the source code file. (This is also not a part of the SL 275 objectives). Java’s popularity is because of the following 3 important points:-

a) Applets b) Security c) Portability

Page 4: Final Unit 1

Java Applets are simple java class files embedded in an html file which is dynamically downloaded across the network by the web server when an appropriate APPLET Tag is encountered. Java Applets are dynamic in the sense that they can respond to events and user inputs and not just simple animations or sounds. Java programs are secure because they run within the JVM (Java Virtual Machine) which will be talked in depth later on. Java achieves the security by confining a java program to the java execution environment and not allowing it to access to other parts of the computer. The other main popularity of java is the fact that it is portable (as already explained earlier).

Features of Java The authors of java had written an influential White Paper that explains the design goals and accomplishments of Java and they are the following which is also called as the features of java. In each of the points the excerpts from the white paper is taken what the java designers say about each buzzword. 1 Simple “We wanted to build a system that could be programmed easily without a lot of esoteric training and which leveraged today’s standard practice. So even though we found that C++ was unsuitable, we designed java as close to C++ as possible in order to make the system more comprehensible. Java omits many rarely used, poorly understood, confusion features of C++ that in our experience bring more grief than benefit”. The basic syntax of Java is a cleaned up version of C++, there is no need for header files, pointer arithmetic, structures etc. There has been a lot of improvement of the C++ language, keeping in touch with the basics of C++. Hence anyone coming into java from the C++ background would find the same very simple. Also a lot of IDEs (Integrated Development Environment) Softwares like JBuilder, Visual Café etc have been made for easy execution of java programs. 2 Object Oriented “Simply stated, object-oriented design is a technique for programming that focuses on the data (= objects) and on the interfaces to that object. To make an analogy with carpentry, an object oriented carpenter would be mostly concerned with the chair he was building and secondarily with the tools used to make it, a non object oriented carpenter would think primarily of his tools. The object facilities of java are essentially those of C++” Java is based on the C++ Model of OOPs which is fundamental in the achievement of the other features of java. Java language is based on the purist’s “everything is an object” paradigm which is simple and easy to extend. The advantages of OOPs are explained in the later sections. The major difference between Java and C++ lies in multiple inheritance for which java has found a better solution. The reflection mechanism and object serialization features make it much easier to implement persistent objects and GUI builders that can integrate off the shelf components. 3 Distributed “Java has an extensive library of routines for coping with TCP/IP protocols like HTTP and FTP. Java applications can open and access objects across the Net via URLs with the same ease as when accessing a local file System.”

Page 5: Final Unit 1

The networking capabilities of Java are fantastic and there is a separate package called java.net having classes related to both Socket Oriented and Packet Oriented data communication. Java also improves on the CGI scripting and uses an elegant mechanism called Servlets and JSP which makes server side programming in java extremely efficient. Java was originally designed for the distributed environment of the internet by properly handling the TCI / IP protocols. In many of the earlier languages the distributed environment was an after thought but not Java. Java has a complete package called java.net which contains classes which take care of the distributed environment like URL, Datagram Packet, Datagram Socket, and URLConnection etc. 4 Robust “Java is intended for writing programs that must be reliable in a variety of ways. Java puts a lot of emphasis on early checking for possible problems, later dynamic (run-time) checking and eliminating situations that are error prone. The single biggest difference between Java and C/C++ is that java has a pointer model that eliminates the possibility of overwriting memory and corrupting data.” Java program is robust by which it will successfully execute reliably in a variety of systems. It was possible to achieve this because of the following features / tools of Java

a) Strictly Typed: Java is a strictly typed language and forces the programmer to find the mistakes early in the program development and it also check the code at compile time and at run time also. It follows strict naming principles also.

b) Good Memory Management: Memory Management is a tedious and difficult

task in the traditional programming environments and it was the duty of the programmer to allocated and de-allocated memory from the programs. In java the de-allocation of memory is completely automatic because there is a Garbage Collection which will automatically reclaim the unused objects. (Garbage Collection is dealt in depth later on in this module).

c) Proper Handling of Exceptions: One of the reasons for the program failure

in the earlier programming languages was the mishandling of exceptional conditions (specifically the run-time errors). Java provides for a proper object oriented way of exceptional handling by which all errors (including run-time errors) can and should be managed by the program.

5 Secure “Java is intended to be used in networked / distributed environments. Towards that end a lot of emphasis has been placed on security. Java enables the construction of virus - free, tamper free systems.” Java achieves this security with the concept of Java Virtual Machine (JVM) which has been explained in depth in the later sections. 6 Architecture - Neutral “The compiler generates an architecture neutral object file format - the compiled code is executable on many processors, given the presence of the Java run-time system. The java compiler does this by generating byte code instructions which have nothing to do with particular

Page 6: Final Unit 1

computer architecture. Rather they are designed to be both easy to interpret on any machine and easily translated into native machine on the fly.” With the advantage of byte codes, it is possible for a java code which is compiled on one machine to be executed on any other machine. This is possible due to the concept of Byte Codes explained earlier. The goal of java was “write once, run anywhere, anytime, forever”. 7 Portable “Unlike the C and C++, there are no implementation dependent aspects of the specification. The sizes of the primitive data types are specified as is the behavior of arithmetic on them.” The main advantages of java are that once written on any platform, it can be executed in the similar way in other platforms also. This is because the data types in Java are having a fixed size and having a fixed size of number types eliminates a major porting headache. The Strings are saved in standard Unicode format. “The libraries that are a part of the system define portable interfaces” 8 Interpreted “The java interpreter can execute Java bytecodes directly on any machine to which the interpreter has been ported. Since linking is a more incremental and light weight process, the development process can be much more rapid and exploratory.” As said earlier Java enables the creation of cross platform programs by compiling into an intermediate representation called Java Bytecode. There is a great advantage while we are developing an application with java being an interpreted language. 9 High Performance “While the performance of interpreted bytecodes is usually more than adequate, there are situations where higher performance is required. The bytecodes can be translated on the fly (at run time) into machine code for the particular CPU the application is running on” The earlier attempts at cross platform were done at the expense of performance. But java although interpreted, was carefully designed so that it would be easy to translate directly into native machine code for very high performance by using a Just-In-Time Compiler. The java runtime systems that provide this feature lose none of the benefits of the platform independent code. 10 Multi-Threaded “The benefits of multithreading are better interactive responsiveness and real time behavior” Multi-Threading is very simply in java and threads in java also have the capacity to take advantage of multi-processor systems if the base operating system does so. The code for the multi-threading remains the same across machines, but the implementation of multithreading is off-loaded to the underlying operating systems. Java supports multi-threaded programming, which allows a programmer to write programs that do many things simultaneously. Java comes with a elegant yet sophisticated but simple and easy solutions for multi-process synchronization that enables a programmer to construct smoothly running interactive systems.

Page 7: Final Unit 1

11 Dynamic “In a number of ways, Java is more dynamic languages that C or C++. It was designed to adapt to an evolving environment. Libraries can freely add new methods and instance variables without any effect on their clients. In java, finding out run time information is straight forward.” Java programs carry with them substantial amounts of runtime type information that is used to verify and resolve accesses to objects at run time. This makes it possible to dynamically link code in a safe and expedient manner.

Concept of JVM The JVM stands for the Java Virtual Machine, an imaginary machine within which all the java programs are executed. The three parts of the JVM are

a) Class Loader b) Byte-Code Verifier c) Interpreter

The duty of the Class Loader is to load all the classes necessary for the successful compilation of the code. Infact the package java.lang is automatically loaded without the need for importing the same (equivalent to the famous first line include statement in C language). After the compilation, a .class file is generated and when we execute the .class file, first of all the Byte Code Verifier is called, whose duty is to check whether any changes have been made to the byte codes after the same have been generated (whether the .class file have been tampered with or not). Incase there is infact a change, it generated an exception or else allows the Interpreter to go ahead with the code. The Interpreter interprets the code and generates the necessary output. The actual working of the Class Loader and Byte Code Verifier will be explained in the first code module. Setting the Path By default the codes can be stored anywhere and when you type javac in the dos-prompt, it would not know whether to look for the javac executable file and hence we need to type as under:- set path=c:\jdk1.3\bin Here we assume that the directory of the JDK is jdk1.3. Once we do this, then we do not have to worry and we can store the .java file where and just type the above set path on the dos-prompt or even put it in the autoexec.bat file, so that we do not have to type it every time.

Page 8: Final Unit 1

Mis-Conceptions of Java The following are the common Mis-conceptions of Java: Java is the Internet version of C++ Although it is very true that java became a popular programming language because of the World Wide Web and have a lot of features of C++, as it is also an Object Oriented Programming language, it would be very wrong to take java as an extension of C++ Java has many advantages over C++ in the form of better memory management and exception handling mechanism. Java is Interpreted language and hence is slow for serious applications The earlier versions of Java was slow and hence a JIT (Just in Time Compiler) and introduce and with this the performance issues simply goes away. Java is great for network related programs because of its intrinsic in-built classes. All Java Programs run inside a Web Page Java Applets run inside a web page, but it is quite possible to write stand alone java programs that run independently of the web browser. Java Applets are major security risk This would not be true because all the java applets run within the Java Virtual Machine and it would not be possible for applets to be in touch with the local file system, which the basic requirement of Java Applets.

Brief explanation of the Important Terminology in Java JDK This is the short form for Java Development Kit. The Java Development Kit is the software which is required for running Java Programs. The development environment for Java is very rich and contains everything they need to get started creating powerful java programs The JDK is available for most operating systems and the current version is JDK 1.3, with the beta version 1.4 due to release very shortly. We have already seen earlier what programs are available under the JDK and the directory structure of JDK. J2SE Java software can be broadly divided into 3 parts namely:

a) Java 2 Standard Edition (J2SE)

Page 9: Final Unit 1

b) Java 2 Enterprise Edition (J2EE) c) Java 2 Micro Edition (J2ME)

J2SE is for developing normal applications and applets, but not for the server side programs for which we required J2EE Software. The program which we work for executing our code is J2SE which we have seen earlier in the module. The structure of the J2SE API is also discussed earlier. The J2SE JDK can be downloaded from the site as under:- http://java.sun.com/j2se/1.3/ Note: J2SE is the same thing as JDK 1.3. J2EE This stands for Java 2 Enterprise Edition, which is specifically for writing server side programs like Servlets, Java Server Pages and Enterprise Java Beans. The J2EE is a set of specifications based on which various Web Servers and Application Servers are said to be J2EE compliant. Java™ 2 Platform Enterprise Edition enables solutions for developing, deploying and managing n-tier server-centric enterprise applications To reduce costs and fast-track enterprise application design and development, the Java 2 Platform, Enterprise Edition (J2EE ) technology provides a component-based approach to the design, development, assembly, and deployment of enterprise applications. The J2EE platform offers a multi-tiered distributed application model, the ability to reuse components, integrated Extensible Markup Language (XML)-based data interchange, a unified security model, and flexible transaction control. Not only can you deliver innovative customer solutions to market faster than ever, but your platform-independent J2EE component-based solutions are not tied to the products and application programming interfaces (APIs) of any one vendor. Vendors and customers enjoy the

Page 10: Final Unit 1

freedom to choose the products and components that best meet their business and technological requirements. J2ME Java 2 Micro Edition is specifically used for writing embedded programs which can be executed on Mobile Phones, PDAs (Personal Digital Assistant) and Palm Tops. Java™ 2 Platform, Micro Edition (J2ME™) encompasses VMs and core APIs specified via Configurations as well as vertical or market-specific APIs specified in Profiles J2ME specifically addresses the vast consumer space, which covers the range of extremely tiny commodities such as smart cards or a pager all the way up to the set-top box, an appliance almost as powerful as a computer. Like the other editions, J2ME maintains the qualities that Java technology has become famous for:

- built-in consistency across products in terms of running anywhere, any time, over any device

- portability of the code - leveraging of the same Java programming language - safe network delivery - applications written with J2ME are upwardly scalable to work with J2SE and

J2EE With the delivery of J2ME, Sun provides a complete, end-to-end solution for creating state-of-the-art networked products and applications for the consumer and embedded market. J2ME enables device manufacturers, service providers, and content creators to gain a competitive advantage and capitalize on new revenue streams by rapidly and cost-effectively developing and deploying compelling new applications and services to their customers worldwide. JVM This stands for Java Virtual Machine and it is within this imaginary machine all the codes whether it is a java application or a java applet is executed. The details of the JVM are explained later on this module. Java Hotspot The Java HotSpot product line delivers the highest possible performance for Java applications. Sun Microsystems has a version of Java HotSpot-technology-based VM for server-side performance and now a version for client-side performance. These two solutions share the Java HotSpot runtime environment, but have different compilers suited to the distinctly different performance characteristics of clients and servers. The Java HotSpot virtual machine (VM) is a key component in maximizing deployment of enterprise applications. It is a core component of Java 2 Platform, Standard Edition (J2SE) software, supported by leading application vendors and technologies. The Java HotSpot VM supports virtually all aspects of development, deployment, and management of corporate applications, and is used by: Integrated development environments (IDEs), including Forte for Java, Community Edition, Borland JBuilder, WebGain VisualCafé, Oracle JDeveloper, Metrowerks CodeWarrior, and the NetBeans Open Source Project

Page 11: Final Unit 1

Application server vendors, such as BEA Systems (WebLogic Server) and iPlanet (iPlanetApplication Server) Plugin Many browsers include a JVM that is used to execute applets. Unfortunately browser JVMs typically does not include the latest java features. The java Plugin solves this problem for us. By using a plugin It directs a browser to use a specific JRE rather than the browser’s JVM. The JRE is a subset of JDK. It does not include the tools and classes that are used in a development environment. Java API API stands for Application Programming Interface and Java API is a set of pre-defined classes which we will be using in our applications and applets. The Java API is not a part of the software download and needs to be downloaded separately from the sun site. JRE JRE stands for Java Runtime Environment. Every java program would require a JRE for the programs to be executed. When we install the JDK, the JRE is automatically installed in the machine and the JRE for the applets is inbuilt into the browser. Hot Java HotJava was initial browser build by Sun Microsystems to show off the powers of java. The builders had in mind the power of what is now called as applets so they made the HotJava browser capable of interpreting the intermediate bytecodes. Nowadays most of the browsers have in-build JRE in the system. JAR This stands for Java Archive and is an executable file which is present in the bin directory of the JDK. The jar.exe is used for creating jar files and has various options by which we can add to an archive, or extract from the archive or delete some files from the archive. JAR (Java Archive) is a platform-independent file format that allows you to bundle a Java applet and its requisite components (.class files, images and sounds) into a single file. Using the new ARCHIVE attribute of the <APPLET> tag, this JAR file can be downloaded to a browser in a single HTTP transaction, greatly improving the download speed. In addition, JAR supports compression, which reduces the file size, further improving the download time. The concept of JAR is very important for the preparation of Java Beans in which we will combine all the java bean codes and then load the jar file in the bean box. This will be explained in Unit 2 when we do Java Beans. AWT This stands for Abstract Window Toolkit which is the GUI part of Java. All the class files related to the GUI part like Buttons, Checkboxes, Menus are all a part of the awt package present in the core java API. We will be doing AWT in Section II of this module later on and all the class files will be explained at that time.

Page 12: Final Unit 1

Swing Swing is a part of the Java Foundation Class and it is used for creating 100% pure java components. The AWT class components rely more on the underlying operating system for their look and feel and hence a component created in Windows will look slightly different from the same component created in Mac machine. However Swing components are pure and full java components and a swing Button created in windows will look exactly the same created in Mac. All the swing components are present in the swing package in the core API. Applets Applets are java class files which are embedded in an html file which is loaded and executed by a web browser. The important classes and interfaces for Applets are present in the applet package of the core java API. Applets are executed within the JVM present in the Web Browser and cannot interact with the local files in the system and hence cannot transmit viruses. Servlets Java Servlets are server-side Java programs that web servers can run to generate content in response to a client request in much the same way as CGI programs do. Servlets can be thought of as applets that run on the server side without a user interface. Servlets are invoked through URL invocation. The main advantage of Servlet is that once started all the future requests are serviced by the service () method of the Generic Servlet or the doGet() and doPost() method of the HttpServlet class. Servlets are a part of the J2EE specifications and we can have session tracking, Http Tunneling and a lot of other server side features with Servlets. JSP It stands for Java Server Pages. A Java Server Page (JSP) is a page much like an HTML page that can be viewed in a web browser. However, as well as containing HTML tags, it can include a set of JSP tags (understood by the server) that extend the ability of the web page designer to incorporate dynamic content in a page. These tags provide functionality such as displaying property values using simple conditionals, and are understood by the server's JSP engine. One of the main benefits of Java Server Pages is that, like HTML pages, they do not need to be compiled. The web page designer simply writes a page that uses HTML and JSP tags, and puts it on their web server. The web page designer does not need to learn how to define Java classes or use Java compilers. JSP pages can access full Java functionality in the following ways:

• by embedding Java code directly in scriptlets in the page • by accessing Java beans • by using server-side tags that include Java Servlets

Both beans and Servlets are Java classes that need to be compiled, but they can be defined and compiled by a Java programmer who then publishes the interface to the bean or the Servlet. The web page designer can access a pre-compiled bean or servlet from a JSP page without having to do any compiling themselves.

Page 13: Final Unit 1

Java Beans

JavaBeans brings component technology to the Java platform. With the JavaBeans API you can create reusable, platform-independent components. Using JavaBeans-compliant application builder tools, you can combine these components into applets, applications, or composite components. JavaBean components are known as Beans. The JavaBeans architecture defines Java's reusable software component model.

Java Beans is a software Component. A bean is a reusable, platform neutral component, which can be visually manipulated in a builder tool. Primarily Java Bean is taken as a black box that is a software device with a known functionality, but unknown internal functioning. The 3 interface facets that can be developed to independent degrees are:

a) The methods that can be invoked on a bean b) The readable and / or writeable properties that the bean expose c) The events that a bean can signal to the outside world or accept from it.

EJB EJB architecture is component architecture for the development and deployment of transactional distributed object applications based server side software components. Applications written using EJB is scalable, transactional and multi user secure. These applications may be written once and then deployed on any server platform that supports the EJB specs.

EJB specifies a server side component model. Using a set of classes and interfaces from the javax.ejb packages, developers can create, assemble and deploy components that conform to the EJB specs. The various parties in the EJB are:

- The Bean: These are reusable business components that companies can purchase and use

to help solve business problems. Beans are not complete applications, but rather are deployable components that can be assembled into a complete solution.

- The Container: This supplies the low-level runtime execution environment needed to run

EJB applications. - The Service Provider: This is the application server logic to contain, manage and deploy

components. BEA, SilverStream, WebSphere, iPlanet etc. - The Application Assembler: This is the overall application architect, for a specific

deployment. The mail goal is to combine various components and write the applications that use components.

- The Deployer: The application made is deployed or installed into one or more application

servers. - The System Administrator: Overall supervision of the deployed systems.

RMI Remote Method Invocation (RMI) enables programmers to create distributed Java-to-Java applications, in which the methods of remote Java objects can be invoked from other Java virtual machines, possibly on different hosts.

Page 14: Final Unit 1

A Java program can make a call on a remote object once it obtains a reference to the remote object, by receiving the reference as an argument or a return value. A client can call a remote object in a server, and that server can also be a client of other remote objects. RMI uses object serialization to marshal and unmarshal parameters and does not truncate types, thereby supporting true object-oriented polymorphism JDBC JDBC is a standard SQL database access interface that provides uniform access to a wide range of relational databases. It also provides a common base on which higher level tools and interfaces can be built. This comes with an ODBC Bridge. All the classes related to database connectivity are in the java.sql package. JDBC does the following things:

a) establish connection with a database b) send SQL statements c) processes the results

JDBC is the interface between the database and java end user application, servlet applet. The Steps in JDBC are

1) Import the necessary classes. 2) Load the JDBC Driver 3) Identify the Data Source 4) Allocate a Connection Object 5) Allocate a Statement Object 6) Execute a Query using the Statement Object 7) Retrieve Data from the returned Result Set Object 8) Close the RS 9) Close the Statement 10) Close the Connection

JNI Java Native Interface (JNI) is a standard programming interface for writing Java native methods and embedding the Java virtual machine into native applications. The primary goal is binary compatibility of native method libraries across all Java virtual machine implementations on a given platform.

The Java 2 SDK extends JNI to incorporate new features in the Java platform. The changes are driven by licensee and user comments.

The Java 2 SDK still supports the old native method interface (NMI), which was originally implemented in Java Development Kit (JDKTM) 1.0. The old NMI is not part of the Java platform standard, and is not supported by the Java HotSpot performance engine.

The JNI allows Java code that runs within a Java Virtual Machine (VM) to operate with applications and libraries written in other languages, such as C, C++, and assembly. In addition, the Invocation API allows you to embed the Java Virtual Machine into your native applications.

Java 2D The Java 2D API introduced in JDK 1.2 provides enhanced two-dimensional graphics, text, and imaging capabilities for Java programs through extensions to the Abstract Windowing Toolkit

Page 15: Final Unit 1

(AWT). This comprehensive rendering package supports line art, text, and images in a flexible, full-featured framework for developing richer user interfaces, sophisticated drawing programs and image editors. The Java 2D is used to display and print 2D graphics in the java programs. Java 2D API enables us to display complex charts and graphs that use various lines and fill styles to distinguish sets of data and also enables you to store and to manipulate image data--for example, you can easily perform image-filter operations, such as blur and sharpen Java 3D

Developers can easily incorporate high-quality, scalable, platform-independent 3D graphics into Java technology-based applications and applets.

The Java 3DTM application programming interface (API) provides a set of object-oriented interfaces that support a simple, high-level programming model. This enables developers to build, render, and control the behavior of 3D objects and visual environments.

By leveraging the inherent strengths of the Java language, Java 3D technology extends the concept of "Write Once, Run Anywhere" to 3D graphics applications.

JNDI The Java Naming and Directory Interface (JNDI) is a standard extension to the Java platform, providing Java technology-enabled applications with a unified interface to multiple naming and directory services in the enterprise. As part of the Java Enterprise API set, JNDI enables seamless connectivity to heterogeneous enterprise naming and directory services. Developers can now build powerful and portable directory-enabled applications using this industry standard. The Java Naming and Directory Interface (JNDI) 1.2 is a major new upgrade release that adds new functionality to the basic naming and directory support offered in the 1.1.x releases. New features include event notification, and LDAPv3 extensions and controls. This release contains valuable contributions from the following companies: Netscape, Novell, Tarantella Inc, Sun, BEA. Java IDL Java TM IDL is a technology for distributed objects--that is, objects interacting on different platforms across a network. Java IDL is similar to RMI (Remote Method Invocation), which supports distributed objects written entirely in the Java programming language. However, Java IDL enables objects to interact regardless of whether they're written in the Java programming language or another language such as C, C++, COBOL, or others.

This is possible because Java IDL is based on the Common Object Request Brokerage Architecture (CORBA), an industry-standard distributed object model. A key feature of CORBA is IDL, a language-neutral Interface Definition Language. Each language that supports CORBA has its own IDL mapping--and as its name implies, Java IDL supports the mapping for Java. CORBA and the IDL mappings are the work of an industry consortium known as the OMG, or Object Management Group. Sun is a founding member of the OMG, and the Java IDL team has played an active role in defining the IDL-to-Java mapping.

To support interaction between objects in separate programs, Java IDL provides an Object Request Broker, or ORB. The ORB is a class library that enables low-level communication between Java IDL applications and other CORBA-compliant applications.

Page 16: Final Unit 1

Java Collections This is the new API introduced in Jdk 1.2. A collection (sometimes called a container) is simply an object that groups multiple elements into a single unit. Collections are used to store, retrieve and manipulate data, and to transmit data from one method to another. Collections typically represent data items that form a natural group, like a poker hand (a collection of cards), a mail folder (a collection of letters), or a telephone directory (a collection of name-to-phone-number mappings). Java 2 provides several types of collections, such as linked lists, dynamic arrays and hash tables for our use. Collections offer a new way to solve several common programming problems. The core of the Collection API is the new set of Interface called Set, Map and List. X.509 Certificates Certificates are digital documents attesting to the binding of a public key to an individual or other entity. They allow verification of the claim that a given public key does in fact belong to a given individual. Certificates help prevent someone from using a phony key to impersonate someone else. In their simplest form, certificates contain a public key and a name. As commonly used, a certificate also contains an expiration date, the name of the certifying authority that issued the certificate, a serial number, and perhaps other information. Most importantly, it contains the digital signature of the certificate issuer. The most widely accepted format for certificates is defined by the ITU-T X.509 international standard and thus, certificates can be read or written by any application complying with X.509 ITU-T Recommendation X.509 [CCI88c] specifies the authentication service for X.500 directories, as well as the widely adopted X.509 certificate syntax. The initial version of X.509 was published in 1988, version 2 was published in 1993, and version 3 was proposed in 1994 and considered for approval in 1995. JPDA The Java Platform Debugger Architecture (JPDA) consists of three interfaces designed for use by debuggers in development environments for desktop systems.

a) The Java Virtual Machine Debugger Interface defines the services a VM must provide for debugging.

b) The Java Debug Wire Protocol defines the format of information and requests

transferred between the process being debugged and the debugger front end, which implements the Java Debug Interface.

c) The Java Debug Interface defines information and requests at the user code level.

RSA Signature Digital Signature are used as a means of security and RSA is the most widely used digital signature algorithm and is employed by most browsers, including Netscape Navigator and Internet Explorer

In previous releases of Java Plug-in the lack of support for RSA signatures and dynamic trust management has impacted the usability and deployment of the Java security architecture.

Page 17: Final Unit 1

In order for Plug-in to be able to verify RSA signatures in a browser-independent way, JDK 1.2.2 has bundled a Cryptographic Service Provider (CSP) with Plug-in. This CSP is capable of verifying RSA signatures. In particular, it supports the "MD2withRSA", "MD5withRSA", and "SHA1withRSA" digital signature algorithms.

The bundled RSA provider is automatically registered with the Java Cryptographic Architecture framework as part of the static initializer of the PluginClassLoader.

Versions of JDK and overview of Improvements and additions

in each version and classes deprecated in various versions till JDK1.2

The initial release of java was revolutionary and it continued to evolve at an explosive pace. After the release of Java 1.0, the features added by java 1.1 were more significant and substantial. JDK 1.1 added many new library elements, redefined the way events were handled by applets and deprecated several features of 1.0. Features added by 1.1

1) Introduction of Java Beans which is software components that are written in java

2) Serialization which allows you to save and restore the state of an object

3) RMI, which allows a java object to invoke the methods of another java object that is located on a different machine. This is very important for distributed applications.

4) JDBC which allows programs to access SQL databases from many different vendors

5) JNI, which provides a new way for the programs to interface with code libraries written in

other languages.

6) Reflection which is the process of determining the fields, constructors and methods of a java object at runtime

7) Various security features, such as digital signatures, message digests, access control

lists and key generation.

8) Built in support for 16 bit character streams that handle Unicode characters

9) Significant changes to event handling that improve the way in which events generated by the GUI elements are handled.

10) Inner classes which allow for one class to be defined within another

Features added by 2.0

1) Introduction of JFC of which Swing is the most important part

2) Introduction of Collection API

Page 18: Final Unit 1

3) More flexible security mechanism is now available for java program. Policy files can define the permissions for code from various sources. These determine for example, whether a particular file or directory may be accessed or whether a connection can be established to a specific host and port.

4) Digital certificates provide a mechanism to establish the identify of a user. You can think

of them as electronic passport.

5) Various security tools are available that enable you to create and store digital signatures, sign JAR files and check the signature of a jar file.

6) The Accessibility library provided feature that make it easier for people with sight

impairments or other disabilities to work with computers.

7) The java 2D API provides advanced features for working with shapes, images and text.

8) Drag and drop capabilities allow you to transfer data within or between applications.

9) Text components can now receive Japanese, Chinese and Korean characters from the keyword. This is done by using a sequence of keystrokes to represent one character.

10) The CORBA defines an Object Request Broker (ORB) and an IDL (Interface Definition

Language). Classes deprecated in various versions till JDK 1.2 In JDK 1.1 The most affected class in the JDK 1.1 was the Date class in which most of the constructors have been deprecated. In JDK 1.2 The most important methods to be deprecated are the suspend (), resume and the stop () methods of the Thread class, because they can typically cause dead lock in the multi-threaded program.

Difference between Java and C / C++ Although most of the C++ syntax has been taken by java the following are the functionalities, which are present in C++ but not in Java.

1) Java does not include structures or unions 2) No automatic conversion done that result in loss of precision. For Example conversion

from long to int must be specifically casted. 3) No global functions or variables. Since code in java programs is encapsulated within one

or more classes 4) No concept multiple inheritance 5) No concept of destructors as the feature of Garbage Collector is there. 6) No goto keyword

Page 19: Final Unit 1

7) Objects are passed by reference only whereas in C++ it can be passed by value or by reference.

The following are the new features in Java not present in C++

1) Multi-Threading 2) Java Package 3) Interface. Although we had the concept of abstract classes, there was not a concept of

interface. 4) There is only the new keyword and no delete keyword in Java 5) The break and continue jump statements can take labels also 6) A new >>> right shift operator 7) A new documentation comment which will be used by the javadoc utility 8) The boolean data type can take only true and false as values.

OOPs Concepts Object Oriented Programming Skills (OOPs) is one of the latest techniques in Programming and is very popular with the concept of Objects. The advantage of OOP is that everything is taken as an object and relationship between the objects. Object oriented programming is like building structures like for example building a Computer. When we use OOP our overall program is made up of lots of different self contained components called as objects. Each object has a specific role in the program and all objects can talk to each other in a well defined way The advantage of OOP is that internally each of the components might be extremely complicated and but we need not know the details of each component. We just need to know the overall system functions because each component talks to one another in a well defined way. In java everything is taken as an object and object oriented programming is the core of java. All computer programs consist of two elements - code and data and a program can be conceptually organized around its code or around its data. The process - oriented model characterizes a program as a series of liner steps (that is code) and can be thought of as code acting on data. In Object oriented programming model the program is organized around its data (that is objects) and a set of well defined interfaces to that data and can be thought of as data controlling access to code. Any object will have two sections within itself that is data and methods. The data is the variables which the object has and the methods are the functions which act on those variables in the object. These two sections can also be called as the State and Behavior where the state is the data and the behavior is the methods within the object. The four fundamental principals of OOPs are:

a) Polymorphism b) Data Encapsulation c) Inheritance d) Data Abstraction

Page 20: Final Unit 1

Polymorphism is taken from the Greek work ‘poly’ which means many and ‘morphus’ which means forms and hence polymorphism would mean many forms. The simplest example of polymorphism would be the ‘+’ operator. When we say 10 + 10 it knows that it has integers on both the sides and it has to perform arithmetic calculation and would give the answer as 20, but incase we say “Hello” + “There” it would know that both the side are strings and it has to add them up or concatenate them.

Polymorphism is supported in java by means of concept of overloading which we will look later in this module. Encapsulation is the mechanism that binds together code and the data it manipulates, and keeps both safe from outside interference and misuse. This is done in java by ensuring that the data in an object can only be accessed by the methods of that object only and incase any other object need to access the data of an object, it cannot do it directly but only through the methods of that object. This feature is like a protective capsule to the data ensuring that only the methods of an object access the data of that object. Inheritance is the process by which one object acquires the properties of another object. The object from which a class inherits is called the super class or the parent class and the class which inherits is called the sub class or child class. Take the example of Animal class which will have two sub classes called Mammal class and Reptile class and this continues. The Inheritance interacts with Encapsulation as well. For example, the Animal class encapsulates some properties / features and all the subclasses will have the same properties plus any of the properties which it adds as part of its specialization. Data Abstraction is the feature of hiding the implementation from the user. For example, when we start the computer, we are not bothered with the complexities of how the computer boots, but once the computer is fully started then we start working with our programs. Similarly when we sit in a car and drivers, we are not bothered with how the steering wheel communicates with the wheels or how the car starts up etc. Similarly when we give a program to a client, we just tell the client to click on the executable file and how the client is abstracted away from the minute details of how the programs functions.

So in simple words Data Abstraction means giving only details which are required by the user and not over-burdening him with many details

Dissecting the First Code Now let’s get to write our first code. We will open any text editor (notepad or edit command in the dos) and type in our code as under: IMP: Remember java is case sensitive, that would mean letters which are supposed to be in Capital should be in Capital only or otherwise specifically. We will now type the following 7 lines of code as specifically written in a file in the text editor (Which can be a Notepad or any other text editor)

Page 21: Final Unit 1

Code public class Test { public static void main (String args []) { System.out.println (“Hello, Welcome to Learning Java with Prof Venkat Krishnan”); } } Points to be noted:

1 All source codes should be done within classes. There can be either one class or more than one class in any source code file.

2 A class is a template for data and is also an object. 3 The opening brace {and the closing brace} define the body of the class or the

method. 4 If the braces do not occur in matching pairs, the compiler indicates an error. 5 Semi-colons at the end of the line is mandatory and omitting the same at the end of a

statement is a syntax error. A syntax error is caused when the compiler cannot recognize the statement. The compiler normally issues an error message to help the programmer to locate and fix the incorrect statements. Syntax errors are violation of the language rules.

6 There should be atleast a semi-colon or an opening brace ( { ) but not both as together at the end of a line.

7 One can call the class whatever you want (within the limits of identifier, which we will see in the next sub-module), but the method, which is executed first in an application, is always called the main ().

8 When you run your java application the method main () will typically cause methods belonging to the other classes to be executed, but the simplest possible java application consist of one class containing the main () method.

9 There can be only one main () in any source code file. 10 There can only be one public class in a source code file. 11 The syntax of the main () is fixed and is public static void main (String args[]) 12 Also note the braces. There will be one set of braces for each and every class and

one for the method. 13 The class name should always be start with a capital Alphabet. This is not mandatory

but is java coding standard. Now let’s see what each of the words in the file is meant:

1 public – This keyword indicates that the class and method is globally accessible. The other access modifiers are default (nothing given), private and protected, which we will see later on.

2 static – The keyword static ensures that it is accessible even though no objects of the

class exist.

3 void – This indicates that the method has no return type. It is mandatory for every method to have a return type and incase there is no return type, the method should be pre-fixed with void keyword.

4 (String args []) – Every method has a (), thorough which we can pass any parameter

required for the method and in this main () we pass the String array having the name args. The array is defined by []. The name of the array can be anything, but it is a convention to type it as args.

Page 22: Final Unit 1

5 System – This is the name of the standard class that contains variables and methods

for supporting simple keyboard input and character outputs to the display. It is contained in a package java.lang so it is always accessible just by using the simple class name, System.

6 out – The object out represents the standard output stream – your display screen and

is a data member of the class System. The member out is a special kind of member of the System class. Like the main () in our program, it is also static. This means that out exists even though there is no object of type System. The out member is referenced by using the class name, System, separated from the member name out by a full stop.

7 println () – This is the println () method that belongs to the object out and that outputs

anything that is within the parameters of the method. Over here we are printing out the text string in the println method.

Now we will name the source code file as Test.java and we will compile the file by going to the dos-prompt and writing javac Test.java. Once the class is properly compiled we will find a .class file with the same name as the source code file. Over here we will check what the class loader which we have learnt earlier is We will try to see what classes are loaded when we are compiling Test.java. We have written in the code two classes String and System. To see what classes are loaded we will compile by writing javac -verbose Test.java. To see what options are available with javac command just type javac and press enter at the console. After writing -verbose command, we will see that a lot of classes are loaded when the code is compiled and finally the .class file is generated and the total amount taken is also mentioned for our reference. Now we will see what a Byte Code Verifier is. We will open the .class file in an editor, it will all be in junk characters, but we will delete one of the legible characters and again type the same character. We have not done anything but only edit the class file to see whether the Byte Code Verifier checks it properly or not. We will now execute the .class file (without re-compiling the same) (by typing java Test) and bingo it refuses to work and will throw an exception. e.g. ClassFormatError. So the Byte Code Verifier indeed does it job. Now we will again recompile the Test.java so that the old class file is overwritten and then execute by calling java Test. When we call the interpreter we will not type any extension after the File name. The Interpreter calls the class file and not the .java file. We can check this by taking the .java file else whether and then calling the interpreter.

Source Code Layout and Comments In a source code, as we have seen earlier, it would contain the class keyword. But the other keywords in the layout would be package and import statement (which we will see later on).

Page 23: Final Unit 1

In a normal source code layout, the package would be the first statement or line in the code layout and will be followed by the import statement (if any) and followed by the class keyword. The above order is mandatory and cannot be changed. Also it is very important to remember that we should not use existing system defined class names as our class names. There are 3 types of comments in java and they are

a) Single Line comment which is \\ b) Multiple Line comment which is \* and ends with *\

c) Javadoc comment which is \** and *\.

A comment is a line which is not read by the java compiler and interpreter when it goes through the source code file. Javadoc is a special comment which is read by the javadoc utility A blank space or white space have no effect in java, as the compiler does not take a white space into consideration other than when it is within a String.

Identifiers An identifier is something which identifies a class, a method name, a variable name, or a parameter name. For example, we have given the class name as Test, so here Test is the identifier and args is the identifier for the String array being passed in the main method and main the identifier etc. An identifier can begin with the following only:-

- May begin with a letter - May begin with a Dollar sign ($) - May begin with a underscore (_)

So any identifier cannot start with a numerical number or any other special character. To try this just change the Test name to 1Test and see the error coming up. Code public class 1Test { public static void main (String args []) { System.out.println ("Hello, Welcome to Gurukul Online Learning Systems"); } } Output

Page 24: Final Unit 1

1Test.java:1: <identifier> expected public class 1Test ^ 1Test.java:7: '{' expected } ^ 1Test.java:1: class <error> is public, should be declared in a file named <error>.java public class 1Test ^ 3 errors

Keywords and Blocks Keywords are words having special meaning to the Java Technology Compiler. They identify a data type name or program construct name goto and const are reserved words in java, which means they are not keywords, but are reserved for future use. There are 48 basic keywords and they are as under:-

abstract do implements private throw boolean double import protected throws break else instanceof public transient byte extends int return true case final interface short try catch finally long static void char float native super volatile class for new switch while continue future null synchronized default if package this

A block is a set of codes which will be executed at once. The block should have the opening braces ( { ) and closing braces ( } ). All methods and classes have blocks which mean that they are executed in one single process.

Variables A variable is a named piece of memory that you use to store information in your java programs – a piece of data of some description. In short variables are locations in memory in which values are stored. If you define a variable to store integers, for example you cannot use it to store a value that is of decimal fraction or a string value

Before you can use a variable, you have to declare it. After it is declared, you can then assign values to it and use it. The declaration does the following -

Page 25: Final Unit 1

a) Tells the compiler what the variable name is, so that it can referenced in future b) Tells the compiler the type of data the variable will or can hold. Java is very particular

about the data type and if you specify any variable can hold integer, then that variable cannot hold any other data type (i.e. String, Double, Float etc) and compiler check for the same.

c) The place of declaration decides the scope of variables, whether the variable is local

variable or class variable or instance variable. Therefore Variables are of 3 kinds namely, Local Variable, Class Variables or Instance Variables. Local Variables - They are local to the method and are visible only inside the method in which they are declared. Incase we try to access the variables outside the method it would throw an error. The important thing to note is that method / local variables need to be initialized or the compiler would throw an error.

Code class Test1 { public static void main (String[] args) { System.out.println(a); } void met1() { int a = 10; } }

Output The compiler would throw an error that it cannot resolve the symbol a. Here the compiler is trying to tell us that it does not understand what a means over here. This is because int a is defined in met1 () and hence becomes a method variable and we are trying to access the same in the main method where it does not have a scope. class Test1A { public static void main(String[] args) { int a; System.out.println(a); } } Output The compiler would throw an error stating that variable is not initialized. This is because the rule is that method variables need to be initialized before being used. Class Variables - These variables are declared outside the main method right in the beginning or right at the end. The scope of the class variable is for all the methods in that particular class.

The class variables need not be initialized as they take default values.

Page 26: Final Unit 1

The Important point to be noted here is that there is only one memory location for the class variables. Default value of a class variable: Data Type Default Value boolean false char \u0000 (that is nothing) byte 0 short 0 int 0 long 0L float 0.0f double 0.0d String null Before we go to the instance variables, we need to understand what the meaning of an instance is. An instance is a copy of the object which we are creating with the new keyword and each instance shall have a copy of the class variables and methods of that object.

For example, if we have a class called Test which has a method called met1() and we need to call the method, then first of all we would be required to create an instance of the class and then call the method with that instance.

Code class Test2 { int a; public static void main(String[] args) { Test2 x = new Test2(); x.met1(); } void met1() { System.out.println(a); } } Output It would be 0 (zero) since it has taken the default value. In the above code we are creating an instance of class Test2 and x is called the instance and with the instance we are calling the method. This is the standard way any non static method needs to be called. Instance Variables: Instance variables are created when objects are instantiated and therefore they are associated with the object. They take different value for each object.

Code class Test4 { int a = 10;

Page 27: Final Unit 1

public static void main(String[] args) { Test4 x = new Test4(); x.a = 20; Test4 y = new Test4(); System.out.println(y.a); } } Output: It would print out 10. This is because when we create a new instance a copy of the class variable is given to each of the instances and hence when we change x.a = 20, we are changing the value of a for the instance x and when we create a new instance it would by default have the copy of the original class variable. Over here it is important to understand that there are 3 separate memory locations, one for the class variable and two memory locations for the two different instances and a separate memory location would be created for any new instance. We learnt what is static earlier on, but now we will properly examine this keyword. static keyword can be applied either to a variable or to a method. When static keyword is applied to a class variable (it can be prefixed only to a class variable, will give a compilation error incase applied to a method variable), then it would mean that class variable would be shared by all the instance of the classes. There would only be one memory location and no different locations for the instance variables. Hence any change made by one instance would change the original class variable also. Let’s see this by way of an example. Code class Test4A { static int a = 10; public static void main(String[] args) { Test4 x = new Test4(); x.a = 20; Test4 y = new Test4(); System.out.println(y.a); } } Output: It would give 20 as the answer, because when we said x.a=20, we are infact changing the original class variable’s value also to 20, since there is only one memory location for the static class variable and instances. Non- static class variables are also called as instance variables. Now let us see what the static keyword means when applied to a method. We have already seen that for a non-static method an instance of a class is required and we can call a non-static method only with the instance of the class. Code class Test5 { public static void main(String[] args) { Test5.met1();

Page 28: Final Unit 1

} static void met1() { System.out.println("Hello World!"); } } Output It would give the output of Hello World. This would mean that for a static method, there is no need for the instance of a class. We can directly call the static method with the class name, since static methods are associated with the class directly. static methods have a limitation however that it can only access static class variables and cannot access non-static class variables. Code class Test6 { int a = 10; public static void main(String[] args) { System.out.println(a); } } Output It would give an error stating that non-static variables cannot be referenced from static context. IMP: Over here one needs to understand the difference between directly printing out the class variable and printing out the class variable with an instance of the class. One of the standard questions in the exam would be why the main method should always be static? The reason is that since the main method is called first by the compiler or it is starting point of entry into a source code file and no instance of the class is created (instances can be created only the main method), hence the main method should be static.

Data Types The data types specify the size and type of values that can be stored in the variable. There is no sizeof operator in Java as the size and representation of all types is fixed and is not implementation dependent. Hence java is called as a strictly typed language. Each primitive data type has a name, specifies how much memory is required to store a data item of that data type, and identifies a legal range of values from which a data item of that data type can be obtained. Again the Primitive data types can be classified into the following 4 major categories

a) Textual Data Type b) Integral Data Type c) Logical Data Type d) Floating Data Type

Page 29: Final Unit 1

Textual Data Type: This is represented by char and individual characters and can hold only single characters - The character should be put inside quotes (‘ ‘) while defining the same. Characters are stored in 16-it Unicode characters and the range is from 0 to 255 and there is no negative char. For example char c = ‘a’; It is important to note that char in C/C++ and in Java are different because in C/C++, char is an integer type with 8 bits wide. Java uses Unicode to represent characters. Unicode defines a fully international character set that can represent all the characters found in all human languages. Since java is designed to allow applets to be written for worldwide use, it makes sense that it would use Unicode to represent characters. The following table lists the special codes that can represent nonprintable characters, as well as characters from the Unicode character set. Characters escape codes.

Escape Meaning \n New line \t Tab

The Integral Data Type can be represented in 3 forms namely;

a) Decimal – Where the decimal value is two b) Octal – Where the leading zero indicates an octal value (E.g. 077) c) Hexadecimal – Where the leading OX indicates a hexadecimal value (E.g. OX22)

The default Integral type is int and for Long it has to be explicitly followed by the letter L. There are 4 types of variables that you can use to store data and all of these are signed that mean you can use both negative and positive values. The four integer types differ in the range of values they can store, so the choice of types for a variable depends on the range of data values you are likely to need. The four integer types are: Type Size Range

byte 8 bits -128 to 127 short 16 bits -32,768 to 32,767 int 32 bits -2,147,483,648 to 2,147,483,647 long 64 bits -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 The smallest integral type is byte. This is a signed 8-bit and is especially useful when you are working with a stream of data from a network or file. short is a signed 16-bit data type IMP: It is very important to note here that integer expressions using byte and short are AUTOMATICALLY PROMOTED to int before the calculation is done. This has a specific reason and will be explained later on. The type long is a 64-bit and is useful for those occasions where an int type is not large enough to hold the desired values

Page 30: Final Unit 1

We should specifically write L (capital alphabet) or l (small alphabet) after the initialized value of a long to ensure that the compiler takes it as a long value, otherwise if we just declare long l = 12345678912, the compiler will take it as a int value and give an error. Code class Test7 { public static void main(String[] args) { long l = 12345678912; System.out.println(l); } } Output The error would be integer number is too large, which proves that in spite of declaring as a long data type, the compiler has taken the default of integral as int. To ensure that the compiler takes it as a long data type, the initialized value should be followed by L and then we would get the desired result. We said earlier that byte and short are automatically promoted to int before any calculation is done on them. This because their values are very small and the final result would be within the size of a byte, but in between the calculation what should be done incase it goes beyond the range. To prevent this, byte and short are automatically promoted to int. For example (10*10*10) / 100 would give answer as 100 but in between the value has gone to 1000 which is beyond the range of a byte. Code class Test8 { public static void main(String[] args) { byte b = 10; byte c = 10; byte d = b + c; System.out.println(d); } } Output: This would a error saying loss of precision since as per the rule byte gets converted into a int during calculations on byte and short and int values cannot be accommodated in a byte value (as int is 32 bits and byte is 8 bits). To ensure that the code gets properly compiled the easy way is to change the data type of d as int. However in many cases, we would want the value of d to be as a byte value only. In this case we would be required to cast the result to ensure that it gets stored in a byte data type and this is done by doing it in the following manner.

byte d = (byte) (b + c); For values which are below 127, there would be no problem and there would serious issues incase the values go beyond the value of 127. To under this let us see the following code

Page 31: Final Unit 1

Code class Test8 { public static void main(String[] args) { byte b = 10; byte c = 13; byte d = (byte) (b * c); System.out.println(d); } } Output The output would be -126. Now we would be thinking how in the world did this figure comes from. Whenever we cast any value into any smaller data type, there would be issue of loss of precision. To understand loss of precision, let us take an example of putting a cup of tea into a saucer fully, it is bound to overflow and some tea would be lost. Similarly when we do casting there would be loss of values. Now let us take the above example and analyze the same. Since the value of 130 is beyond the range of a byte as the maximum value of a byte would be only 127, it again goes back and starts putting the bytes in the old blocks. Remember the range of a byte is from -128 to 127. So the value of 128 is put in -128 and so on and hence the result of -126. It is very important to note incase the value is very big, it will go on doing the above thing till it reaches -1 and then 0 and then 1 and till 127 and again -128 and till keep on going like this. In Java, the only logical data type is boolean which takes only two states, true or false. In java, unlike C and C++ boolean is neither a number nor it can be treated as one. All tests of boolean should test for true or false. Also note that boolean states are in small caps and not like other languages where true should mandatorily be declared as TRUE and vice versa. It is also important to note that boolean values cannot be converted or casted with other data types also. The boolean data type is used by the control statements like if and for etc. Floating-point numbers are also known as real numbers are used when evaluating expressions that require fractional precision. There are two kinds of floating point types, float and double which represent single and double precision numbers in the width and range as under:

Type Size Range

float 32 bit 3.4e-038 to 3.4e+038 double 64 bit 1.7e-308 to 1.7e+308

The default of floating point data type is double and hence for using float we should mandatorily use f after the values (like long). Code class Test9 { public static void main(String[] args)

Page 32: Final Unit 1

{ float f = 10.11; System.out.println(f); } } Output It would give an error of loss of precision, since it has taken the default value of a double.

Coding Conventions Classes should start with Capital Alphabets. The class will compile incase we have a small alphabet class, but then it is a convention followed in the java world and hence we would like to differ from the general rules of convention. The second letter incase one is there in the class should also start with Capital alphabets. For Example IndexArrayOutOfBoundsException. The methods should start with lower alphabets and the second word in the method should be capital. For example. startsWith (), endWidth() or getDocumentBase() methods. The interfaces should also follow the rules layed down for classes. The packages should start with small alphabets. For Example java.lang, java.awt. etc All variables (class and method) should start with small alphabets and the second word should start with Capital Alphabets like the rule for methods. Although the $ sign is permitted as an identifier, we should try to limit the use of $ sign in the class names, because it was a special meaning when we are using the Inner classes.

Arrays Array is a group of similar kind of data types that is reference by a common name. Suppose if we want a group of integers from 1 to 100 to be reference by a common name, we create an array of them. Each variable in an array is called array element. It is important to note that the array numbering stars from 0 and not 1. Array is an object and not a primitive, even if it is made up of primitives. Like objects, array required initialization and declaration only creates a reference to the array. To explain in depth, to create a array is to 3 steps

a) Declaration b) Creation c) Initialization

Declaration One is not obliged to create the array itself when you declare the array variable. The array variable is distinct from the array itself. This is how one declares a array.

Page 33: Final Unit 1

int a [] - This is a array of integers with the variable a String s [] - This is a array of strings with the variable s

Creation Once you declare an array of any data type, you should create the same with the help of the new keyword and the same is done like this a = new int [10]; s = new String [5]; The above example shows that the array with the variable a will store integers up to 10 values and the second example creates that the s (String variable) will store Strings up to 5 values.

Remember: The array length starts from 0 The creation of array only reserves the space in memory for 10 integers and 5 strings, but nothing is inside it.

Initialization Once we have the memory reserved, we can put values into each of the individual spaces like this: a[0] = 10; This puts 10 as the first value of the array a[1] = 20; This puts 20 as the second value of the array and so on. Similarly we can put strings into the 5 spaces as under; s[0] = “Gurukul” and so on.

Direct Declaration and Creation The above 1 and 2 steps can be do simultaneous like this int a [] = new int [10]; It is important to note that the [] box can be put before or after the array variable. This is also correct. int [] a = new int[10];

Direct Initialization Since the above process is cumbersome, we can initialize an array with your own values when you declare it and at the same time determine how many elements it will have. This is done as below:

Page 34: Final Unit 1

int a [] = { 1,25,30,55} This creates an array with variable name as a and with values as put into the {} and with 4 elements.

Accessing Array Values You can refer to an element of an array by using the array variable followed by the element’s index value enclosed between square brackets. For Example Existing Array: int a [] = { 1,25,30,55} If we have to access the 2nd element of the array, we will do it like this int a[1], here we use 1 because, as said earlier, the array indexing begins with 1. Important: Any attempt to access array indexes beyond the length of the array causes runtime error. For example: If we try to access the 5th element, it will give a runtime error, because there is no 5th element in the array. The exception thrown would be called as ArrayIndexOutOfBoundsException. We will cover the topic of runtime error and the different types of exceptions thrown in the other modules. Code class Test22 { public static void main(String[] args) { int a [] = new int[10]; System.out.println(a[10]); } } Output java.lang.ArrayIndexOutOfBoundsException at Test22.main(Test22.java:6) Exception in thread "main"

Array Bounds In the java programming language, all array subscripts begin at zero. The number of elements in an array is stored as part of the array object, as the length attribute. This value is used to perform bounds checking of all runtime accesses. If an out-bounds access occurs, then a runtime error occurs. Use the length attribute to iterate on an array as follows: int list[] = new list [10]; for (int I = 0 ; I < list.length ; I++) { System.out.println[i];

Page 35: Final Unit 1

) Using the length attribute makes the program maintenance easier

Array resizing Once created, an array cannot be resized. However you can use the same reference variable to refer to an entirely new array. Since an array cannot be resized, this is the biggest limitation of arrays. int d[] = new int [6]; d = new int [10]; In this case, the first array is effectively lost unless another reference to it is retained elsewhere.

Array Copying The java language provides a special method in the System class arraycopy () to copy arrays. The syntax for copying array is: System.arraycopy ( original array, 0 (index to start with), new array, 0 (index of new array from where copying has to start), original array.length (or number of references to be copied); The above method can be proved with the help of this example. // original array. int a[] = {1,2,3,4,5,6}; // new larger array. int d[] = {10,9,8,7,6,5,4,3,2,1}; System.arraycopy{a,0,d,0,a.length); After this, the array d will have the following content: 1,2,3,4,5,6,4,3,2,1} Note: The method System.arraycopy() copies, references, not objects, when dealing with array of objects. The objects themselves do not change. Code class Test23 { public static void main(String[] args) { int a[] = {1,2,3,4,5}; int b[] = {10,20,30,40,50,60,70,80}; System.arraycopy(a,2,b,3,2); for (int i = 0; i<b.length;i++) { System.out.println(b[i]+" "); } }

Page 36: Final Unit 1

} Output

10 20 30 3 4 60 70 80 Multi-Dimensional Arrays We have only worked with one-dimensional arrays up to now, that is arrays that use a single index.

Why would you ever need the complications of using more indexes to access the elements of an array? Suppose that you have a fanatical interest in the weather and you are intent on recording the temperature each day at 10 separate geographical locations throughout the year 1999. Once you have sorted out the logistics of actually collecting this information, you can use an array of 10 elements corresponding to the number of locations, where each of these elements is an array of 365 elements to store the temperate values. You would declare this array with the statement float temperature [] [] = new float [10] [365]; There are 10 arrays each having 365 elements. In referring to an element, the first square brackets enclose the index for a particular array, and second pair of square brackets encloses the index value for an element within that array. So to refer to the temperate for day 100 for the sixth location, you would use temperature [5] [99]. In java, multidimensional arrays are actually array of arrays. To declare a multidimensional array a variable, specify each additional index using another set of square brackets. For example, the following declares a two-dimensional array variable called D. int D [] [] = new int [2] [4] The above array creates and allocated a 2 by 4 array. Internally this acts like a matrix in which the first square bracket is for the number of rows and the second bracket is for the number of columns. Remember: Note that you can have an array with 0 columns but not with 0 rows. For example int D[] [] = new int [2] [0] - Ok int D[] [] = new int [0] [2] - Not Ok.

Page 37: Final Unit 1

Java Operators Java provides a fully featured set of operators, most of which are taken fairly directly from C and C++. However Java’s operators differ in some important aspects from their counterparts in these other languages and you need to understand clearly how java’s operators function. The Java Operators can be classified into 8 Groups as under:

a) Unary Operators b) Arithmetic Operators c) Comparison Operators d) Bitwise Operators e) Short-Circuit Operators f) Ternary Operators g) Assignment Operators

The Unary operators can be classified further into :

1) Increment and Decrement Operators; ++ -- 2) Unary plus and minus Operators; + - 3) The boolean complement operators; ! 4) The Cast operator; ()

Increment and Decrement Operators These operators modify the value of an expression by adding or subtracting 1. So for example, if an int variable x contains 10, then ++x results in 11 and --x give you 9. This is the case because the increment and decrement is done on x and the value is stored in x only To understand how the position of these operators’ ++x and x++ affect their operation, you must understand the different between the values stored by these operations and the result value they give. For example, you could say y = x++; then the value assigned to y will be the original value of x and if you say y = ++x, then the value assigned to y will be 1 more than the original value of x. It is important to note here that in both these cases the value of x will be increment by 1. The following table shows the value of x and y, before and after particular assignment using these operators: Initial value of x Expression Final Value of y Final value of x 10 y = x++ 10 11 10 y = ++x 11 11 10 y = --x 9 9 10 y = x-- 10 9 The Unary + and – operators The unary + and – operators are distinct from the more common binary + and – operators which are usually referred to as + and – (add and subtract).

Page 38: Final Unit 1

The unary + has no effect beyond emphasizing the positive nature of a numeric literal. Unary – negates an expression. So one might make a block of assignment just like this: x = -3; y = +3; z = -(y+6); The Boolean Complement Operator ! This operator inverts the value of a boolean expression so !true gives false and !false would give true. This operator is usually used in the body of if() and else() to be swapped. The Cast Operator Casting is used for explicit conversion of the type of an expression. This is only possible for plausible target types. The compiler and runtime system check for conformance with typing rules and incase they do not match, then casting might be required. Casts can be applied to change the type of primitive values, for example forcing a double value into an int value like this: int c = 10; double b = 15.50; int d = (int) (c x b);

Arithmetic Operators The next highest in precedence, after the unary operators are the arithmetic operators. The Arithmetic Operators are divided into two further sub groups, the first group having the *, / and % operators. The second group have the lower precedence + and – operators. Multiplication and Division Operators The above operators can be used on all primitive numeric types and char. Integer division can generate an ArithmeticException from a division by zero. The multiplication and division works as it works in simple math examples which we learnt in school. The important point to note here is that, whether you multiply or divide two integers, the result will be calculated using the integer arithmetic in either int or long representation and u will have to store the same in the wider of the types to ensure that precision is maintained. Modulo Operator % The modulo Operator gives a value which is related to the remainder of a division. It is generally applied to two integers, although it can be applied to floating point numbers also. For example when you say int a = 7 int b = 3 int c = a % b the result would be 1. The Addition and Subtraction Operators

Page 39: Final Unit 1

The + and – operators perform addition and subtraction and they apply to operands of any numeric type, but uniquely, the + operator is also permitted when either of the operand is a String object. When either of the operands of a + expression is a String object, the meaning of the operator is changed from numeric addition to concatenation of text. In order to achieve this, both operators must be handled as a text. If both operators are in fact String objects, this simple, however if one of the operands is not a String object, then the non string operand is converted to a String object before the concatenation is taken place. How operands are converted into String Objects?? It is very useful in practice to know a little about how + converts operands into String objects. For object types, conversion to a String object is performed simply by invoking the toString () of that object. The toString () is defined in the java.lang.Object class which is the root of the class hierarchy and therefore all objects have a toString () method. Conversion of an operand of primitive type to a String is typically achieved by this, indirectly using the conversion utility method in the wrapper classes. For example, the following code explains the situation. Code class Test11 { public static void main(String[] args) { int a = 10; String s = "Hello"; System.out.println(a+s); } } Output The output would be 10Hello. But how did it convert the primitive data type of int to a String, so that it can be concatenated with s. This is properly explained in the following code. Code class Test11 { public static void main(String[] args) { int a = 10; String s = "Hello"; Integer i = new Integer(a); String s1 = i.toString(); System.out.println(s1+s); } } Output The output would be the same as 10Hello, but we have properly explained the procedure over here. First of all the primitive int is converted into an Object via the use of Wrapper classes (set of classes provided for each primitive data type for conversion into an object). Please note

Page 40: Final Unit 1

that there is no class specifically called as Wrapper class, all the classes together are called as Wrapper classes, since the purpose of these classes is to wrap the primitive into an object. IMP: The rule for the + operator is that if both sides are primitives it would perform arithmetic calculation and incase one side is a String, it would convert the other side to a String and then do concatenation. The process would be from left to right.

Code class Test12 { public static void main(String[] args) { String s = 10 + 10 + "Hello"; String s1 = "Hello"+10+10; System.out.println(s); System.out.println(s1); } } Output : The output would be 20Hello and Hello1010. The first output is 20 because for the first + operator both the sides are numeric and hence it performed arithmetic calculation and then concatenated the result with the String because the second + operator had a String on one of its side.

The Comparison Operators The comparison operators all return a boolean value. There are three types of comparison:

a) Ordinal - Which tests the relative value of the numeric operands b) Object Type - Which tests if the runtime type of an object is of a

particular type or subclass of that particular type

c) Equality - Which test if two values are the same and may be applied to values of non-numeric types also.

Ordinal Comparison operators are of the following type: Operator Meaning Example < Less than x < 3 > Greater than x > 3 <= Less than or equal to x <= 3 >= Greater than or equal to x >= 3 Object Type comparison is done with the help of the instanceof Operator This is the operator, which tests the class of an object at runtime. The left-hand argument can be any object reference expression, usually a variable, while the right hand operand must be a class, interface or array type. You cannot use a java.lang.Class object or its string name as the right hand operands.

Page 41: Final Unit 1

The instanceof operator returns true if the class of a left hand argument is the same or is some subclass of the class specified by the right hand operand. The right hand operand may equally well be an interface. In such a case, the test determines if the object at the left hand argument implements the specified interface. Note: If the left hand argument is a null type, the instanceof test simply returns false – it does not cause an exception. Code class Test13 { public static void main(String[] args) { A x = new A(); B y = new B(); C z = new C(); boolean k = x instanceof B; boolean l = y instanceof A; // boolean m = z instanceof B; System.out.println(k); System.out.println(l); } } class A { }; class B extends A { }; class C extends A { }; Output: It would be false and true. Over here we have class A which has 2 subclasses. Now we have introduced a new keyword called extends. It is this keyword which makes possible inheritance possible in Java. Then we create 3 instances of each of the classes. Since all comparison operators return a boolean value, we are capturing the same in a boolean variable. First we check whether x is a instanceof B and it return false because a superclass instance cannot be a instance of the subclass. Then we check whether y is a instance of A and it returns true because a subclass variable is a instance of the subclass and also of the super class since the subclass extends the super class.

Page 42: Final Unit 1

incase we remove the comment and printout the variable m also, it would result into a compilation error because there cannot be a relationship between two unrelated classes. It will not give false also, but a compilation error. Equality comparison operators: == and != and equals() The Equality comparison can be on two grounds:

a) Checking the Memory location equality (whether both the variables being checked belong to the same memory location or not).

b) The content Equality. (checking the contents of the String)

The operators == and != test for equality and inequality, respectively returning a boolean value. For primitive type, the concept of equality is quite straightforward and is subject to promotion rules so that for example a float value of 10.0 is considered equal to a byte value of 10. For variables of object type, the “value” is taken as the reference to the object; typically this is the memory address. You should not use these operators to compare the contents of objects, such as Strings because they will return true if two reference refer to the same object, rather than if the two objects have an equivalent meaning. Code class Test14 { public static void main(String[] args) { String s = "Hello"; String s1 = "Hello"; String s2 = new String ("Hello"); String s3 = new String ("Hello"); boolean a = s == s1; boolean b = s1 == s2; boolean c = s2 == s3; System.out.println(a); System.out.println(b); System.out.println(c); } } Output: It would be true, false and false. Now before we go to the result, we need to understand what do one mean by memory location. There are two parts of a computer memory, a stack and a heap. In the earlier programming languages, String was a primitive data type, but in java, they wanted it to be an object and also as a data type and hence String is the only class which can be created without the new keyword. When String is initialized without the new keyword it is taken as a primitive data type and when it is initialized with the new keyword it is taken as a proper object. Hence we cannot call the methods of a String object on the primitive data type.

Page 43: Final Unit 1

The rules for Stack and Heap are as under:-

a) primitive data types are always stored in the stack. b) The rule in the stack is that, once we have a particular value, a memory location is

allotted to it and when another variable is initialized to the same value, a different memory location is not created, but the same memory location now points to both the variables.

c) Objects are always stored in the heap.

d) Whenever a object is created with a new keyword a new memory location is created

irrespective of the contents of the Object. Now based on the above rules, we can analyze the above code as under:-

a) Both the String values of s and s1 would be stored in the stack. b) Since both the values of s and s1 are the same, it would have the same memory

location and hence s == s1 returns true.

c) Now s2 and s3 are created with the new keyword and hence they would be allotted separate memory locations, in the help although they have the same contents.

d) Hence s2 == s3 would return false.

e) s1 == s2 would definitely give false, because they are in separated areas of memory.

To achieve a in-depth comparison, so that two different String objects containing the text “Hello” are considered equal, you must see the equals() rather than the == method. IMP: We have a equals method in the Object class, which is similar to the == method which checks for the equality on the basis of the memory location. However in the String class the equals method have been overridden to check for the equality on the basis of contents. Check the following code Code class Test15 { public static void main(String[] args) { String s = new String ("Hello"); String s1 = new String ("Hello"); StringBuffer sb1 = new StringBuffer("Hello"); StringBuffer sb2 = new StringBuffer("Hello"); boolean a = s.equals(s1); boolean b = sb1.equals(sb2); System.out.println(a); System.out.println(b); }

Page 44: Final Unit 1

} Output The answer would be true and false. This is because as said earlier, the equals method have been overridden in the String class to check for the contents whereas in the StringBuffer class the same have not been overridden and hence it checks like the normal equals method which is the memory location and since both are object created with the new keyword, they would have different memory locations and hence false.

Bitwise Operators The Bitwise Operators &, ^ and | provide AND, Exclusive-OR (XOR) and OR Operations respectively. They are applicable to internal types. The bitwise operations calculate each bit of their results by comparing the corresponding bits of the two operands on the basis of these 3 rules:

a) For AND Operations, 1 and 1 produces 1 and any other combination produces 0 b) For XOR Operations, 1 XOR 0 produces 1 as does 0 XOR 1 and any other combination

produces 0

c) For OR Operation 0 OR 0 produces 0 and any other combination produces 1 The names AND, XOR and OR are intended to be mnemonic for these operations. You get 1 result from an AND operation if both the first operand and second operand are 1. An XOR gives 1 result if one or the other operand, but not both (the exclusivity part) is 1. In the OR Operation, you get 1 result if either the first operand or the second operand (or both) is 1 Code class Test16 { public static void main(String[] args) { int a = 10; int b = 15; int c = a & b; int d = a | b; int e = a ^ b; System.out.println(c); System.out.println(d); System.out.println(e); } } Output The answer would be 10, 15 and 5 To check this let us first take a scientific calculator and out the bit pattern of 10 and 15. The bit pattern of 10 is = 1010 The bit pattern of 15 is = 1111

Page 45: Final Unit 1

(please remember that int is of 32 bits and since there are zeros in the beginning it is not coming the calculator, but for calculation purpose we need to work out the 28 initial zeros also. Now each bit in the first value will be calculated with the first bit of the second value and similarly all the 32 bits are calculated and then finally whatever bit number comes it is converted in to a integer comes and that is how the values of 10, 15 and 5 came in the above example. Bitwise on Boolean Operations The &, ^ and | operators behave in fundamental the same way when applied to arguments of boolean rather than integral types. However instead of calculating the result on a bit by bit basis the boolean values are treated as single bits, with true corresponding to a 1 bit and false to a 0 bit. The general rules discussed in the previous section may be modified like this when applied to boolean values

a) For AND Operations, true AND true produces true and any other combination produces false.

b) For XOR Operations, true XOR false produces true or false XOR true produces true and

any other combination produces false. For OR Operation, false OR false produces false and for any other combination produces true. Operator Meaning ~ Bitwise complement <<= Left shift assignment (x = x << y) >>= Right shift assignment (x = x >> y) >>>= Zero fill right shift assignment (x = x >>> y) x&=y AND assignment (x = x & y) x|=y OR assignment (x = x | y) x^=y XOR assignment (x = x ^ y)

Short Circuit Logical Operators The short circuit logical operators && and || provides logical AND and OR operations on boolean types. Note that there is no XOR operation provided. Superficially this is similar to the & and | operators with the limitation of only being applicable to boolean values and not integral types. However the && and || operators have a valuable additional feature: the ability to short-circuit a calculation if the result is definitely known. This feature makes these operators central to a popular null-reference-handling idiom in java programming. The main difference between the & and && and the | and || operators is that the right hand side operand might not be evaluated at all. This behavior is based on two mathematical rules that define conditions under which the result of a boolean AND or OR operations is entirely determined by one operand without regard for the value of the other:

a) For a AND operation, if the Left Hand operand is false, the result is false, without regard to the other operand.

b) For an OR operation, if the Left Hand is true, the result is true, without regard to the other

operand.

Page 46: Final Unit 1

Given these rules, if the left hand operand of a boolean AND operation is false, the result is definitely false whatever the right hand operand may be. It is therefore unnecessary to evaluate the right hand operand. Similarly, if the left hand operand of a boolean OR operation is true, the result is true and the right hand operand need not be evaluated. For Example if ((s != null) && (s.length() > 20)) { System.out.println(s); } Now here if the String reference is null, then calling the s.length() method would raise a NullPointerException. If we use the short-circuit && then that situation would not arise, because if (s != null) returns false, then the whole test expression is guaranteed to be false. Where the first operand is false then in && the second operand is not evaluated at all and the s.length () is not evaluated at all. The Ternary Operator:

The ternary operator provides a way to code simple situations (if/else) into a single expression. The syntax for a ternary operator is (boolean condition) ? true : false. Here the boolean condition is evaluated and if the result is true then the value of the expression after the ? is evaluated (here true) otherwise it is the value after the colon will be evaluated ( here false). The sub expressions (true and false) on either side of the colon must have the same type. Example: int a = 10; int b = 20; inc c = (a>b)?40:50. This will give the value of c as 50, since (a>b) returns false and hence the right hand side of the colon will be evaluated.

Assignment Operators The assignment operators set the value of a variable or expression to a new value. Simple assignment uses =. Besides simple assignments, compound “calculate and assign” is provided by operators such as += and *=. These operators do the calculation and then assigns. The point to be noted here with the right hand operand must be a type that is assignment compatible with the left hand operand. Expression Meaning x += y x = x + y x -= y x = x - y x *= y x = x * y x /= y x = x / y

Page 47: Final Unit 1

Loops in Java The Flow Controls in java is broken in to 3 modules which are as under:

b) Loops c) Selection statements d) Jump statements

The loops in java are

a) The for loop b) The while loop c) The do-while loop

The for Loop A common requirement in programming is to perform a loop so that a single variable is incremented over a range of values between two limits. This is frequently provided for by a loop that uses the keyword for. The primary purpose of the for loop is to execute a block of statements a given number of time. The for loop syntax is for (initialization ; loop condition ; increment expression) { body of the loop; } The control for the for loop appears in parentheses followed by the keyword for. It has three parts separated by semi-colons.

1. The first part, initialization is executed before the execution of the loop starts. This is typically used to initialize a counter for the number of loop iterations, for example i = 0. With a loop controlled by a counter, you can count up or doing using a integer or a floating point variable. It is only used to set up a starting conditions.

2. The second part is the loop condition, which means the execution of the loop continues

as long as the condition you have specified in this is true. That means the loop conditions should be a boolean conditions which will either return a true or false. This loop conditions is checked at the beginning of each loop iteration and when it is false the execution stops and the program continues with the statement after the loop. A simple example of loop conditions is i < 10, which would mean that the loop would execute as long as the variable has a value less than 10 and the moment it increases the value of 10, the loop conditions will retune false the loop stops.

3. The third part the increment expression, is executed immediately after the body of the

loop, just before the test is performed again. Commonly this is used to increment the loop counted. This could be i++, which will increment the loop counter by one. Of course you might want to increment the loop counter in steps other than one and in that case you can write i +=2, in which case the loop counter gets increment by 2.

Example for (int i = 0 ; i<5 ; i++)

Page 48: Final Unit 1

{ System.out.println(“The value is now “ + i); } System.out.println(Out of the loop now); The above code prints The value is now 0 till The value is now 5 and then Out of the loop now. The execution is done in the following way

a) First of all the loop is initialized to 0, then it check whether the boolean condition is true and in this case it is true since 0 is less then 5, then it goes into the body and the statement” The value is now 0 is printed..

b) Then it goes to the Iteration statement and this increments the value of the loop counter

to 1

c) Then it again check the boolean condition and this continues till the boolean condition is false and once it is false, it comes out of the loop.

d) Then the statements after the loop are executed.

Note: The for () loop allows the use of comma operators in a special way. For example for (int i = 0, j = 0 ; j <10 ; i++, j++) { } The above code initialize int i and int j to 0, the checks the boolean condition or conditions and then increments both the variables. IMP: The loop condition should always return a boolean value, otherwise the compiler will throw an error.

The while Loop The while loop executes as long as the given logical expression in the parentheses is true and stop when the conditions becomes false. The syntax for the while loop is; while (boolean condition) { Statement; } It is important to note here that the condition is checked at the beginning of the loop and hence if the condition is false initially, then the loop will not execute at all. Note here that in java the conditions can only be a boolean condition, while in C and C++ it can be a variety of types. The statement or statements will be executed again and again until the boolean condition becomes false. If the condition will never become false, then it will be a infinite loop. Code class While

Page 49: Final Unit 1

{ public static void main(String[] args) { int a = 0; while (a < 10) { System.out.println(a); a++; } } }

The do – while Loop The do – while loop is similar to the while loop and the only difference is that the boolean condition is after the body of the loop, which means that even if the condition is false, the loop will be executed atleast one. In programming, this loop is very important where we want a particular statement to execute atleast once. The syntax for the do loop is; do { statement; } while (boolean condition) Each iteration of the loop first executes the body and then evaluates the conditional expression. If this expression is true, then it will execute the body again and then checks for the condition and this goes on till the condition becomes false. IMP: In general programming all of the above loops is used together and all the above loops can be nested also. The main difference between the while and do-while loop is that incase the condition is false, the do-while loop will be executed atleast once, whereas the while loop will not be executed at all. Code class DoWhile { public static void main(String[] args) { do { System.out.println("Hello"); } while (false); } } Output Hello

Page 50: Final Unit 1

Selection statements in Java Java supports if – else and switch as its selection statements and we will discuss both of them in this section if Statement The if statement is used to route programs execution to different paths depending on a particular condition and the syntax for the same is; if (condition) { Statement; } else { Statement; } As in the earlier cases, the condition checking the flow of control is a boolean condition and if the condition is true, then the if part body will be executed or the else part of the body will be executed.

Example int a ; int b ; if (a>b) { int c = a; } else { int c = b; } In the above example we want the value of int c to be the higher value amount a and b and this we do not know and hence we will use the if loop and if (a>b) then the value of int c will be the value of a and if int b is higher then the value of int c will be the value of int b as stated in the else part of the body.

Nested ifs A nested if is an if statement that is the target of another if or else. Nested ifs are very common in programming and when you nest a if, the important point to remember is that an else statement always refer to the nearest if statement that is within the same block as the else.

Page 51: Final Unit 1

It is very important that you use block of codes, when using the nested ifs or otherwise you will find a result other than what you were expecting. if-else-if ladder The if-else-if ladder syntax looks like this if (condition) { Statement; } else if (condition) { Statement; } else if (condition) { Statement; } else { Statement; } The if condition in the first if will be considered and like the normal if-else will not go to the else part, but it will check the else if condition and like this it goes down the ladder. After the last else if is encountered and then also the condition is not true then the else statement at the end of the ladder will be executed. Remember, if the last else statement is not there and if all the else if condition returns false then nothing will be executed. switch Statement If you need to make a choice between multiple alternative execution paths and the choice can be based on a non-boolean value, then you should use the switch () construct as we cannot use the if-else loop. The syntax is as under: switch (expression) { case value1: { Statement; } case value2: { Statement; } case value3: {

Page 52: Final Unit 1

Statement; } default: { Statement; } IMP: It is very important to note here that the expression must be of type byte, short, int or char and each of the values in the cases (e.g. case value1 ....) must be type compatible with the expression and each case should be a unique (e.g. it should not be a constant or a variable). Duplicate case values are also not allowed. IMP: There is a fundamental difference between the switch in C++ and java wherein we need to mandatorily use the break statement to jump out once the case have been matched, otherwise the control will enter all the cases and then reach the end of the loop. To understand the meaning of the above statement, please have a look at the following code. Code class Test17 { public static void main(String[] args) { for (int i = 0;i<3 ;i++ ) { switch (i) { case 0: { System.out.println("Zero"); } case 1: { System.out.println("One"); } case 2: { System.out.println("Two"); } default: { System.out.println("Default"); } } // end of switch cases } // end of for loop } // end of main method. } Output : Zero One Two Default One Two

Page 53: Final Unit 1

Default Two Default The above output is because of the lack of break statements after the cases and hence once the case is matched, the code enters all the subsequent cases and printout out the same (including the default). To ensure only one case is matched and the code to exit the switch block, we will see the following code where there is a break statement after the cases. Code class Test17 { public static void main(String[] args) { for (int i = 0;i<3 ;i++ ) { switch (i) { case 0: { System.out.println("Zero"); } break; case 1: { System.out.println("One"); } break; case 2: { System.out.println("Two"); } break; default: { System.out.println("Default"); } } // end of switch cases } // end of for loop } // end of main method. } Output: Zero One Two We will see later on what is the significance of the break keyword. The switch starts off with a expression and the value is compared with each of the literal values in the case statements and if a match is found then the body of that case value is executed and if none of the case values are matched the default block is always executed. The default is optional here and if no matching case if found and there is no default then nothing will be executed.

Page 54: Final Unit 1

One can use the break statement inside a switch to terminate a statement sequence. When a break statement is encountered, the execution branches to the first line of code that follows the entire switch statement. The switch statement differs from the other loops in that the switch can only test for equality, where as the other loops test for boolean condition. That is the switch looks only for a match between the value of the expression and one in its case and has nothing to do with the boolean conditions.

Jump statements in Java The three jump statements in java is the break statement, the continue statement and the return statement. The java’s jump statements help in transferring control to another part of the program.

Using break statements Break can be used for 3 reasons

a) breaking out of the switch statements b) breaking out of a loop c) Labeled break to enable transfer to a particular point in the code.

We have seen how to break out of a switch statement in the earlier code.

Using Break to exit out of a loop We can use break to force immediate termination of a loop and thereby bypassing the conditional expression and any remaining code in the body of the loop. When break statement is encountered inside a loop, the loop is terminated and the program control resumes at the next statement following the loop. Let’s see a example Code class Test { public static void main(String args[]) { for (int i=0 ; i<100 ; i++) { if (i==10) { break; } System.out.println(“The value of loop is “ + i); } System.out.println(“ The loop is complete”); } }

Page 55: Final Unit 1

Output: The above program is to print the numbers from one to hundred, but we are having a if condition which states that if i is equal to 10, then it should break out of the loop and then it will print the statement that loop is complete. The above program generates numbers till “The value of i is 9” and then will exit out of the loop and then the next statement that “The loop is complete” will be printed out. The following points are also important regarding the break statement:

a) The break statement is used to exit out of infinite loops. b) When used inside nested loops, the break statement will come out of the innermost loop

and the execution of the outer loops will continue.

Using Labeled Break Java also makes a labeled break available to you, by which you can exit out of any block with the respective block name. It is not necessary that it have to be a loop or switch. The labeled break enables you to break out to the statement following an enclosing block that has a label regardless of how many levels there are. You might have nested blocks and you can exit out of any nested block or blocks by using the respective block name (label) and the only important point here is that you will have to name the block with the name. For Example Block 1 { Block 2 { Block 3 {

if (true) { break Block 2 (here i can break out of any block, either 3,2 or 1) } } } The break statement inside block 3, tells to break out of block 2 and hence the point of execution will be switched here and any statement after the break will not be executed. } Code class Test19 { public static void main(String[] args) { one:{ Two:{ Three:{ System.out.println("Before Break"); if (true) { break Two; } System.out.println("After Break"); } System.out.println("After Three");

Page 56: Final Unit 1

} System.out.println("After Two"); } System.out.println("After One"); } // end of main } // end of class Output: The output would be Before Break After Two After One This is because; any statement after the break within a block of codes is never executed and we are specifically telling the compiler to break out of the block named as Two and the cursor would be positioned outside the block Two and then all the statements would be executed. Points to remember

a) Whenever we are having labeled block of codes, and we want to break outside, we always need to give the block name from which to break and a simple break statement would not work. Let us remove the block Two from the break and it would throw the following exception.

Test19.java:11: break outside switch or loop break ; ^ 1 error

b) We need to put the break inside the if (true) block or otherwise the following error would be generated. (comment the if block and just give break Two; inside the block Three)

Test19.java:13: unreachable statement System.out.println("After Break"); ^ 1 error

Continue Statement Sometimes it is useful to force an early iteration of a loop. That is, you might want to continue running the loop, but stop processing the remainder of the code in its body for this particular iteration. For example, Incase we need to print out the values from 1 to 10 in a for loop but print only the odd numbers, we will be using the continue statement. Code class Test20 { public static void main(String[] args) { for(int i =1 ; i <= 10 ; i++)

Page 57: Final Unit 1

{ if (i % 2 == 0 ) { continue; } System.out.println(i); } } } Output 1 3 5 7 9 In the above example we are checking in the if loop incase the remainder is equal to 0 to go to the next iteration and not complete the block of the for loop. This will ensure that it does not print out the System.out.println() statement. The continue statement can appear anywhere within a block of loop statements.

New Keyword We have already seen the use of the new keyword earlier, when we created a instance of a class and also we used the same in arrays. Now let us see in depth what does the new keyword means and what it does. If we have to create an object for a particular class, the same can be done with the help of a new keyword. For example class Test { int a; int b; double c; } The above class is just a template for any object creation and a new object is created with the help of the following syntax: Test a = new Test(); Here a is just a handle for the Test and is an instance of Test. When you create an object of class Test, it will have its own copy of the instance variables defined by the class. Thus every Test object will have its own copies of int a, int b and double c. Over here it is important to note that a is a variable that refer to an object. The following examples create new instances of the classes String, Random and store those new instances in variables of the appropriate types: String str = new String ();

Page 58: Final Unit 1

Random r = new Random(); The parentheses are important; don't leave them off. The parentheses can be empty (as in these examples), in which case the most simple, basic object is created; or the parentheses can contain arguments that determine the initial values of instance variables or other initial qualities of that object: Date dt = new Date (90, 4, 1, 4, 30); Point pt = new Point (0,0); The number and type of arguments you can use inside the parentheses with new are defined by the class itself using a special method called a constructor (you'll learn more about constructors later). If you try and create a new instance of a class with the wrong number or type of arguments (or if you give it no arguments and it needs some), then you'll get an error when you try to compile your Java program.

Memory allocation and layout When variables of any primitive type - that is boolean, int, etc - are declared, the memory space is allocated as part of the operation. The declaration of a variable using a non-primitive type – that is an object does not allocate space for the object. It is the new keyword that implies allocation and initialization of storage. Getting Values To get to the value of an instance variable, you use an expression in what's called dot notation. With dot notation, the reference to an instance or class variable has two parts: the object on the left side of the dot and the variable on the right side of the dot. IMP: Dot notation is an expression used to get at instance variables and methods inside a given object For example, if you have an object assigned to the variable myObject, and that object has a variable called var, you refer to that variable's value like this: myObject.var; This form for accessing variables is an expression (it returns a value), and both sides of the dot can also be expressions. This means that you can nest instance variable access. If that var instance variable itself holds an object and that object has its own instance variable called state, you could refer to it like this: myObject.var.state; Dot expressions are evaluated left to right, so you start with myObject's variable var, which points to another object with the variable state. You end up with the value of that state variable after the entire expression is done evaluating.

Changing Values Assigning a value to that variable is equally easy-just tack an assignment operator on the right side of the expression: myObject.var.state = true;

Page 59: Final Unit 1

Constructor As already stated the new keyword dynamically allocated memory for an object. We can create an object of a class with the new keyword and the class name is followed by parentheses specifies the constructor for the class. Constructor’s basic purpose is to initialize the class variables of a class when an object of the class is created. Most of the real world classes define their own constructors and incase there is no explicit constructor defined in a class, java provided its own constructor. A constructor always has the same name as the class in which it is defined, has no return type specified, and must not include a return statement. You can always specify a constructor with any parameters as the arguments and anything in the body, which will be guaranteed to be initialized when we use the new keyword. A default constructor has nothing in its body and has no arguments in it. The constructor is an unusual type of method because it has no return value. This is distinctly different from a void return value, in which the method returns nothing but you still have the option to make it return something else. Constructors return nothing and you don’t have an option. If there were a return value, and if you could select your own, the compiler would somehow need to know what to do with that return value.

Example using constructor:

class Test { int a,b,c; Test() { System.out.println(“This is inside the constructor”); a = 10; b = 5; c = 5; } int met1() { return int d = a x b x c; } public static void main (String arg[])

Page 60: Final Unit 1

{ Test t = new Test(); Test s = new Test(); int z = t.met1(); int y = s.met1(); System.out.println(z); System.out.println(y); } }

Result: The result will be

This is inside the constructor

This is inside the constructor

250

250

As you will see both the object variables z and y were initialized with the constructor Test, when they were created. Since the constructor gives all the object the same dimensions, the volumes with both the object are 250.

With the new keyword a constructor is called, if available and if not a default constructor is called. The default constructor initializes all instance variables to zero. But it is important to note that once you define your own constructor, the default constructor will not be called. Points to note:

1) Constructor is like a method but without a return type, whereas the methods always need a return type.

2) The basic purpose of the constructor is to initialize the class variables.

3) Constructor of a class is classed dynamically when a instance of a class is created,

whereas needs need to be explicitly called.

4) Constructor of a class should have the same name as the class name, whereas the method can have any name.

Page 61: Final Unit 1

Constructors make like easy for us and we will now consider two examples to prove this point further. Now consider we have two class variables a and b which should take different values for calculation and a method met1() which multiplies the class variables and give the output. Code class Test25 { int a,b; public static void main(String[] args) { Test25 x = new Test25(); x.a = 10; x.b = 20; x.met1(); Test25 y = new Test25(); y.a = 40; y.b = 50; y.met1(); } void met1() { int c = a * b; System.out.println(c); } } Output 200 2000 Without a constructor we need to mandatorily create instance of the class and then with the class instance initialize the class variables. For separate set of values for the class variables, we need separate instances. They with the instances we call the method met1(). Code class Test26 { int a, b; Test26(int x, int y) { a = x; b = y; } public static void main(String[] args) { Test26 x = new Test26(10,20); x.met1(); Test26 y = new Test26(40,50); y.met1();

Page 62: Final Unit 1

} void met1() { int c = a * b; System.out.println(c); } } Output 200 2000 The output would be the same, but we saw how life is made easier for us with the use of the constructor to initialize the class variables and we pass values to the parameters of the constructors. Parameter: This specifies what values can be passed inside a method or a constructor. for example Test26 (int x, int y), we specify that the constructor should take two int values. Arguments: This is the actual values passed in to the parameter of a method or a constructor. for example Test26 (10,20), over here we pass the values of 10 and 20 which will call the constructor and the values of 10 will be passed to int x and 20 will be passed to int y and inside the constructor we initialize the class variables with the two values passed in the constructor. Default Constructor: Until now we have created instances, without knowing the concept of constructors at all. This would mean incase we do not have a constructor within our class then the JVM will provide us with a default constructor which is a constructor with no parameters. Incase we define our own parameterized constructor, then the system will no longer provide us with the default constructor and we need to specifically create a no parameter constructor ourselves. Code class Test27 { int x; public static void main(String[] args) { Test27 x = new Test27(); } Test27(int a) { x = a; System.out.println("class variable initialised"); } } Output Test27.java:6: cannot resolve symbol symbol : constructor Test27 () location: class Test27

Page 63: Final Unit 1

Test27 x = new Test27(); ^ 1 error This above code would prove our point. Now to ensure that our code functions, create a default constructor (constructor with no parameter) and our code will function properly.

Page 64: Final Unit 1

Determining the class of an Object Want to find out the class of an object? Here's the way to do it for an object assigned to the variable obj: String name = obj.getClass().getName(); What does this do? The getClass() method is defined in the Object class, and as such is available for all objects. The result of that method is a Class object (where Class is itself a class), which has a method called getName(). getName() returns a string representing the name of the class. Now over here we would like to bring to your notice that the superclass of all objects in java is the class Object which is there in the java.lang package. As said earlier the java.lang package is imported by default and incase we need to use any other class which is not there in the lang package we would need to import the package specifically otherwise the compiler will cry. IMP: All classes by default extend the Object package. Code class Test24 { public static void main(String[] args) { Test24 x = new Test24(); Class c = x.getClass(); String s = c.getName(); System.out.println(s); } } Output Test24 Whenever we need to find out the class name of an object we would be using the getClass() and the getName() methods.

Page 65: Final Unit 1

this keyword Every instance method has a variable with the name, this which refers to the current object for which the method is being called. This is used implicitly when your method refers to an instance variable of the class.

In the body of a method definition, you may want to refer to the current object-the object in which the method is contained in the first place-to refer to that object's instance variables or to pass the current object as an argument to another method. To refer to the current object in these cases, you can use the this keyword. this keyword can be used anywhere the current object might appear-in dot notation to refer to the object's instance variables, as an argument to a method, as the return value for the current method, and so on. In many cases you may be able to omit the this keyword entirely. You can refer to both instance variables and method calls defined in the current class simply by name; the this is implicit in those references. Note Omitting the ‘this’ keyword for instance variables depends on whether there are no variables of the same name declared in the local scope. Keep in mind that because this is a reference to the current instance of a class, you should only use it inside the body of an instance method definition. IMP: Class methods-that is, methods declared with the static keyword-cannot use this. Code class Test28 { int x, y; public static void main(String[] args) { Test28 z = new Test28(10,20); z.met1(); } Test28(int x, int y) { this.x = x; this.y = y; } void met1() { System.out.println("The value of x is = "+x+" The value of y is = "+y); } }

Page 66: Final Unit 1

Output The value of x is = 10 The value of y is = 20 In the above example, we have a parameter x and a class variable whose name is also x. So we cannot say x = x. So over here we need to tell the compiler that the parameterized x should be passed into the class variable x and for this we do this.x = x, where this.x refers to the class variable. Remember that incase there is a name conflict (a class variable has the same name and the local variable has the same name) when we just the variable, we are calling the local variable, because the local variable hides the class variable inside the method. The second use of this is to call another constructor of the same class within a constructor as in this example. This concept is explained in the topic “Overloaded Constructors”.

Introducing Methods We have already seen what a method is and how it functions etc in our examples till now. We know that all methods need to have a mandatory return type and incase the method is not returning anything then void keyword should be prefixed to the method name. Methods that you define for a class provide the actions that can be carried out using the variables specified in the class definition. Method is a self-contained block of code that has a name and has some property that it is reusable – the same method can be executed from as many different points in a program as you require. A method is executed by calling the method using its name, as will see and a method may or may not return a value, but the return type is mandatory before the method name. The general form of a method is: <modifier> <any other key word> turn-type> <name> (<argument list>) throws <exception (if any)> { block of code; } There are 6 parts of the method and they should appear in the following order from left to right.

a) Access Modifier (public, private, protected or nothing which amounts to default). This determines the accessibility of the method. We will at a later stage go into each of the different modifiers

b) Any other keyword (like static, final, abstract) and within this it can appear in any

order.

c) Return type of the method.

d) Name of the method. The name is the name of the method, by which it will be referenced later on in the source codes

Page 67: Final Unit 1

e) Parameters of the method. The argument list allows argument values to be passed into a method. Elements of the list are separated by a comma, while each element consists of a type and an identifier.

f) throws statement, incase a method throws any exception (this will be dealt with in the

next module). The throws (exception) clause cause a runtime error (exception) to be reported to the calling method so as to handle it in a suitable manner

Incase a method returns anything, then the respective data type of the return should be prefixed before the method name and there should be a mandatory return statement as the last line in the method. What the method return type is declared in the signature of the method (the data type the method is declaring that it will return) should be within the conversion rules of primitive data types. If the method returns anything it must be specified before the modifiers name and if not so the compiler will give a compile time error. Java is very particular about what the method returns. If we write that the method returns int and incase it returns any other data type, the compiler again will complain. Use the return command within a method to pass back a value. For example, incase a method declares in the signature that it would return a int data type, then the actual return type can be byte, short or int, but not any other data type which is larger than int (more than 32 bits). Code class Test30 { public static void main(String[] args) { Test30 x = new Test30(); x.met1(); } int met1() { System.out.println("Inside met1"); } } Output Test30.java:10: missing return statement { ^ 1 error The compiler will cry here. So to make the above code run, we should have a mandatory return statement at the end of the method like return 0 (zero). The following points are just revision to the points that we have already mentioned earlier.

a) Similar to the variables, there are also two methods known as instance methods and class or static methods.

Page 68: Final Unit 1

b) One can execute class methods without any object of the class also, whereas for instance methods, an object of the class should be there. Since the class methods are declared using the static keyword, they are also called as static methods.

c) Since class methods are executed when there are no objects in existence, they cannot refer to instance variables. This is quite sensible – if you think about it - trying to operate with variables that might not exist would be bound to cause trouble. Java will not allow you to try and will give a compile time error.

d) The best example of a class / static method is the main method and you declare the same with the keyword static. This is because the main() is the method from where the execution starts in an application and before an application can start no objects will exist and hence the main() will have to be declared as static.

Accessing Variables and methods In many circumstance, you would want to refer to a constant or a variable or a method of a particular class in another class. There are two rules for it

a) A static member of a class can be accessed using the class name, followed by a period, followed by the member name. With a class method, you also need to supply the parentheses enclosing any arguments to the method after the method name. The period here is called the dot operator. So if you want to calculate the square root of PI you could access the class method sqrt() and class variable PI that is defined in the Math class as follows: double a = Math.sqrt (Math.PI);

b) Instance variables and method can only be called using an object reference, as by

definition they relate to a particular object. The syntax is exactly the same as we have outlined for static members.

Overloading of Methods

As already discussed earlier overloading is the important concept in OOPs which allows the feature of polymorphism in java. Overloading of methods means having the same method name, but different type and order or parameters and depending on the values passed, the program would know to call which method. Code class Test31 { public static void main(String[] args) { Test31 x = new Test31();

Page 69: Final Unit 1

x.met1(10); x.met1("Hello",20); } void met1(int a) { System.out.println("Method with one parameter"); } void met1(String s, int a) { System.out.println("Method with two parameters"); } } Output Method with one parameter Method with two parameters So here we can conclude that the program knows how to call a method inspite of having the same name on the basis of the parameters passed into the method. IMP: Overloading cannot be done on the basis of different return types. Return Type itself is not sufficient for overloading of methods. It can only be done on the basis of different type and order of parameters. To explain the above point, have a look at the following code. Code class Test32 { public static void main(String[] args) { Test32 x = new Test32(); x.met1(10); x.met1(20); } int met1(int a) { System.out.println("Method with return type as int"); } void met1(int a) { System.out.println("Method with return type as void"); } } Output Test32.java:15: met1(int) is already defined in Test32 void met1(int a) ^

Page 70: Final Unit 1

1 error Since overloading cannot be done on the basis of the return type and also the parameters are the same, the compiler is complaining that we already have a method with the same name, as we cannot have the same identifier used twice.

Overloaded Constructors Overloading is the basic feature of OOPs wherein you have the same method / constructor name but different type and order of parameters. Let us take the example of a website where in you need the users to input their name and salary. There are 4 possibilities in this case

a) User inputs his name but not his salary b) User inputs his salary but his name c) User input both salary and name d) User inputs neither salary nor name.

Now let us see how to we code this. We also want the above data to be there in the table wherein incase there is no name, “unknown” should be there and where no salary is there, 0 should be the amount value. Code public class Test29 { String name; int salary; public Test29 (String n, int s) { name = n; salary = s; System.out.println("The name entered is = "+name+" and the salary is = "+salary); } public Test29(String n) { this(n,0); } public Test29(int s) { this("unknown",0); } public Test29() { this ("unknown"); } public static void main(String arg[]) { Test29 a = new Test29("ABC"); // user inputting only name Test29 b = new Test29(1000); // user inputting only salary Test29 c = new Test29("XYZ",20000); // user both name and salary Test29 d = new Test29(); // user inputting neither name nor salary

Page 71: Final Unit 1

} } Output The name entered is = ABC and the salary is = 0 The name entered is = unknown and the salary is = 0 The name entered is = XYZ and the salary is = 20000 The name entered is = unknown and the salary is = 0 IMP: Any call to this, if present, must be the first statement in any constructor.

How argument values are passed. This is one of the most important and the most confusing part of java fundamentals. The fundamental rule for understanding how argument values are passed is:-

a) Primitive Data Types are always passed by value b) Objects are always passed by reference.

Now what do one mean by how values are passed? This would mean when we declare something in the parameter of a method and when actual argument is given to that method, depending on the whether the argument value is a primitive or a object, the values are actually passed in the method. In java, all arguments values that belong to one of the basic primitive types are transferred to a method using what is called the pass-by-value mechanism. All this means is that for each argument value that you pass to a method, a copy is made and it is the copy that is passed and referenced through the parameter name and not the original value. This implies that if you use a variable of any of the basic primitive types as an argument, the method cannot modify the value of the main variable in the calling program. For example; Code class Test33 { public static void main (String arg[]) { int i = 10; Test33 t = new Test33(); int z = t.met1(i); System.out.println("The value of the variable captured from the method is "+z); System.out.println("The value of the actual method variable is " + i); } int met1(int a) {

Page 72: Final Unit 1

++a; return a; } } Output The value of the variable captured from the method is 11 The value of the actual method variable is 10 So we can finalize the concept over here that whenever we pass a primitive data type as the argument to the method, it would always be passed by value and the original value remains unchanged. In the above example, what is passed as an argument to the met1() is a copy (value) of i and not the actual i and hence what is returned is 11, caught by int z, while the value of i remains contact at 10. Passing objects to a method. Until now we have seen that only simple types are parameters to methods. However it is very common and correct to pass objects to methods. One of the most common use of object parameters involves constructors. Frequently you will want to construct a new object so that it is initially the same as some existing object. To do this, you must define a constructor that takes an object of its class as a parameter. Passing objects to the parameter is known as call-by-reference. In this method, a reference to an argument (and not the value of the argument) is passed to the parameter. Inside the method, this reference is used to access the actual argument specified in the call. This means that changes made to the parameter will affect the argument used to call. Code class TestTemp { int a,b; TestTemp (int i, int j) { a = i; b = j; } void met1( TestTemp o) { o.a *= 2; o.b /= 2; } } class Test34 { public static void main (String arg[]) { TestTemp z = new TestTemp(15,20); System.out.println("Value before call " + z.a+ " " + z.b); z.met1(z); System.out.println("Value after first call " + z.a+ " " + z.b); z.met1(z);

Page 73: Final Unit 1

System.out.println("Value after second call " + z.a+ " " + z.b); } } So we see here that when we pass an object as an argument to a method, then it is passed by reference, which means what is passed is the memory location of the address and any changes made in the method also gets reflected in the original also.

Access Modifiers We have already studied about encapsulation, which links data with the code that manipulates it. Encapsulation also provides another important feature and that is Access Control. It is through encapsulation that you can control what parts of the code (that is variables and methods) can be accessed by members of other classes which call upon code from your class. There are 4 types of access control modifiers which can be used to control the visibility of the methods and class variables.

a) public b) private c) default (when we do not write any modifier also called as friendly) d) protected

We will explain over here the first two modifiers and the other two modifiers are associated with the concept of packages and hence we will be covering the same in the other sub-module.

Public Access Modifier When a member of a class is having a public access modifier then that member can be accessed by any other code in your program. Remember our original program whether we had used public access modifier in our main (). This is done so to enable the code outside the program – that is the Java run-time system to call it.

Private Access Modifier There are many situations when we want some data members or methods which access those data members to be accessed by that class and not to be accessed by any other class either by way of inheritance or by way of creation of objects. This can be done by prefixing the members of the class with the keyword private. The variables / methods prefixed with the private access modifier can be used only within that particular class. Other classes, which extend this class, also cannot access these variables. This keyword provides the maximum security. For Example

Page 74: Final Unit 1

class Test { public static void main (String arg[]) { int i = 10 private int j = 10 } } class Test1 extends Test { public static void main (String arg []) { System.out.println (j); // it is not possible to access j since it is private. } } With the help of the above code we can generalize that the private keyword class variable is accessible only with the class in which it was created and not even in the sub-class of that method. Protected Access Modifier If a variable or a method is prefixed with this modifier then it will be accessible to all classes in the same package as well as in another class in another package provided the following two conditions are met:-

a) The class in the other package extends the original class b) An instance of sub class is created.

Default Access Modifier If a class or a method or a variable do not have any access modifier, then it is called as default or friendly access modifier. The visibility of this modifier is in all classes in the same package, either by creating an instance or by virtue of inheritance. Example: Now we are going to create two packages and two classes in each of the packages and show the usage of all the above modifiers. package one; public class Pack1 { static private int x=10; static int y; static protected int z=30; } package one; public class Pack2 extends Pack1 { public static void main(String[] args)

Page 75: Final Unit 1

{ System.out.println(y); System.out.println(z); } } package one; public class Pack3 { public static void main(String[] args) { Pack1 p=new Pack1(); //System.out.println(p.x); System.out.println(p.y); System.out.println(p.z); } } package two; import one.*; public class Pack4 extends Pack1 { public static void main(String[] args) { Pack4 a=new Pack4(); System.out.println(a.z); Pack1 x = new Pack1()// will give an error System.out.println(x.z); // will give an error } } Note: For further explanation, you need to call Prof. Venkat Krishnan on 98214-22745

static Initializing block As we already know a block is a code which is enclosed in a set of braces so that it is executed together. A initialization block is a block of code between braces that is executed before an object of the class is created. This is normally used with the static keyword and this block is executed once when the class is loaded.

The main purpose of the static initialization block is:

a) To initialize static data members of the class.

b) To load the library files of other languages so that the same can be used within the java using native keyword. (this is not a part of the java certification).

All the other methods are initialized after the static initialization block. If you want your variables to be started with a particular values, then you can put the same in the static initialization block and can then use the variables in the other methods.

Page 76: Final Unit 1

Incase there are multiple static initializing block, then they are executed in the order of their appearance and the static class variables take the value as present in the last block. Code class Test35 { static int a; static { a = 10; } public static void main(String[] args) { System.out.println(a); } static { a = 50; } } Output 50 This would be 50 because, initially in the first static block it got initialized to 10 and then it again got initialized to 50 before entering the main block. Pls remember that all static blocks would be executed before entering the main method. Please remember that inside the static blocks do not again declare the variable and incase you do that, then it would be taken as another variable and not the class variable. See the following code for this purpose. Code class Test35 { static int a; static { a = 10; } public static void main(String[] args) { System.out.println(a); } static { int a = 50; } } Output 10 The output is 10 because in the second static block we are again saying int a = 10 and this a and the class variable a are two different entities.

Page 77: Final Unit 1

How Constructors are called When there is multi level hierarchy, in what order are constructors called. The constructors are called in the order of derivation from superclass to subclass. It is important to note here that this order is followed irrespective of whether super () is used or not. If super () is not used, then the default or parameter less constructor is used. ( we will study about the super keyword in the next sub-module). Code class Test36 { public static void main(String[] args) { Three x = new Three(); } } class One { One() { System.out.println("Constructor in One class"); } }; class Two extends One { Two() { System.out.println("Constructor in Two class"); } }; class Three extends Two { Three() { System.out.println("Constructor in Three class"); } }; Output Constructor in One class Constructor in Two class Constructor in Three class This would prove that the original constructor of the super most class is loaded first and then it goes down the hierarchy. This is logical since the methods of the super class can be called with the sub class instance variable and hence the super class should be loaded in the memory. By calling the constructor of the super class that class is loaded in the memory.

Page 78: Final Unit 1

Please note that the sub-most class would call its super class default constructor which in turn will call the constructor of its super class and this process will go on till the super most classes’ constructor is loaded. Now incase if there is no default constructor anywhere in the hierarchy then the loading of the classes would stop and a compilation error would be generated. This is why we had insisted earlier that when we define our own constructors, it is our duty to also provide for a default constructor also. Code class Test36 { public static void main(String[] args) { Three x = new Three(); } } class One { One() { System.out.println("Constructor in One class"); } }; class Two extends One { Two(int a) { System.out.println("Constructor in Two class"); } }; class Three extends Two { Three() { System.out.println("Constructor in Three class"); } }; Output Test36.java:28: cannot resolve symbol symbol : constructor Two () location: class Two { ^ 1 error What the compiler is trying to tell us by the above error is that it cannot find a default constructor in class Two. We can make the code compile properly by provide for a default constructor.

Page 79: Final Unit 1

is - a and has - a relationship In programming language, one often creates a model of something (for example, an employee) and then need a more specialized version of that original model. For example, you might want a model for a manager, which only has more features but is still an employee. The Is-a relationship in java is done with the help of extends keyword which creates a new class from an existing class, by sub-classing it. For Example: class Employee { String name; int salary; Date hiredate; } class Manager extends Employee { String department; } In the above example, when we sub-class the class Manager, the Manager class will have all the variable and methods that an Employee has. All these variables and methods are inherited from the definition of the parent class. The class Manager then adds additional functionality to itself by defining its own variables and methods. The has-a relationship comes when a particular variable or method is inside a particular class. For example in the above class Employee, we can safely say class Employee has a name. So we can safely finalize by saying that is-a relationship is for sub-class and super-class relationship and is for variable inside the class.

super keyword The super keyword refers to the superclass of the class in which the keyword is used. It only refers to the immediate super class and not up the hierarchy. The super keyword has two general forms:

a) The super keyword is also used to invoke the parent class’s constructor from the child class’s constructor. For this one should use the super keyword in the first line of the child class’s constructor.

IMP: If one uses the super with no argument in the child’s class’s constructor, then this will call the default parent class constructor and if such a constructor is not available in the parent class, then a compile error results. For Example: class Employee

Page 80: Final Unit 1

{ String name; pubic Employee (String s) { name = s; } } class Manager extends Employee { String department; public Manager (String s, string d) { super(); // this will cause a compile error, because there is no default

//constructor in Employee. super(s) // this will work department = d; } } When a subclass calls super, it is calling the constructor of its immediate superclass and which constructor to call would depend on the parameters being passed in the super keyword argument. IMP: We had seen earlier in the order in which constructors are called, the sub class automatically calls the super class default constructor and this is possible because there is a implicit super in the sub class which calls the super classes’ default constructor every time. Code class Test38 extends TestTem { int d; public static void main(String[] args) { Test38 l = new Test38(10,20,30); l.area(); l.volume(); } Test38( int x, int y, int z) { super(x,y); d = z; } void volume() { int e = a*b*d; System.out.println("The volume is = "+e); } }

Page 81: Final Unit 1

class TestTem { int a, b; TestTem( int x, int y) { a = x; b = y; } void area() { int c = a*b; System.out.println("The area is = "+c); } };// end of class Output The area is = 200 The volume is = 6000 In the above code, we have two variables in one class and another variable in the sub-class. The sub class constructor initializes all the 3 variables, by providing the values and the sub class constructor call the super class constructor which will initialize the two variable in that class and then calls the area and volume methods. We can call the area method also, because the Test38 class extends TestTem class. The main purpose of the super keyword is to ensure that there is no duplication of efforts and more over when we need to specifically call a super class constructor from inside the child classes’ constructor IMP: The super keyword incase is there in the constructor should be the first line in the sub classes’ constructor or else the compiler would throw an error. IMP: The super and this keyword cannot be accessed from inside a static method.

b) The second use of super is to refer to the member variables or methods of the superclass that is hidden by the subclass.

This is also like this, except that it always refers to the superclass of the subclass in which it is used. The syntax for the same is: super.member. (Here the member can either be a variable or a method) It is used more in those cases when the variable name of a subclass hides the members by the same name of the superclass. For Example: class First { int i; } class Second extends First {

Page 82: Final Unit 1

int i; Second (int a, int b)// constructor { super.i = a; i = b; } void method() { System.out.println( “ This is superclass i “ +super.i); System.out.println( “ This is superclass i “ +i); } class Super { public static void main (String args []) { Second s = new Second(10,25); s.method() } } This example shows how to use the super keyword in the second context.

Method overriding Overriding is one of the basic features of the Object Oriented Programming. If a method is defined in a subclass that has the same name and return type exactly as that of the superclass (or parent class), then the new method is said to override the old one. When an overridden method is called from within a subclass, then it will always refer to the version of that method defined by the subclass. Note: Remember that methods with the same name, but with different argument lists that are in the same class are simply overloaded and not overridden. Overriding is fundamental to the OOPs principals because it allows for the subclasses through the inheritance to add more specialized features which inheriting the generalized features of the sub class.

For Example: The Source Code file name should be Tes.java class One { void show() { int i = 10; int j = 20; System.out.println(" The value of i and j are " + i+""+j); }

Page 83: Final Unit 1

} class Two extends One { void show() { int a = 50; int b = 60; System.out.println(" The value of a and b are " + a+""+b); } } class Tes { public static void main(String arg[]) { Two t = new Two(); t.show(); } } This will print out the show () of the object, which is created. If one has to use the show () of the superclass then we can use the same as super.show (), which will use the show () of the super class.

Rules about overriding methods The following rules are mandatory and apply to overridden methods:

a) The return type of overriding method must be identical to the method it overrides. This would mean that even if the arguments are the same, but return type is different, then it would be neither overloading nor overriding and infact the compiler will think that one is trying to over ride the method and give an error.

Code class Test39 extends Temp { public static void main(String[] args) { Test39 x = new Test39(); x.met1(); } int met1() { System.out.println("Inside Test39 class"); } } class Temp { void met1() {

Page 84: Final Unit 1

System.out.println("Inside Temp class"); } }; Output Test39.java:9: met1() in Test39 cannot override met1() in Temp; attempting to use incompatible return type found : int required: void int met1() ^ 1 error

b) An Overriding method cannot be less accessible that the method it overrides. This would

mean that if a method has a particular access modifier then the overriding method couldn’t have a modifier, which makes it less accessible.

Now the accessibility from the least accessible to the most accessible is in the following order: private - default - protected - public (we will cover protected and default later on, but just remember that this is the order). Code class Test40 extends Temp { public static void main(String[] args) { Test40 x = new Test40(); x.met1(); } void met1() { System.out.println("Inside Test40 class"); } } class Temp { public void met1() { System.out.println("Inside Temp class"); } }; Output Test40.java:9: met1() in Test40 cannot override met1() in Temp; attempting to assign weaker access privileges; was public void met1() ^ 1 error

Page 85: Final Unit 1

The compiler is trying to tell us the overriding method (met1() in Test40) cannot be less accessible that the method which it is trying to override (met1() in Temp). So to make the code compile we need to have the access modifier of the overriding method in Test40 to have atleast the same level of accessibility or more. This can be done by making the method met1() as public in Test40.

c) An overriding method cannot throw higher class types of exception that the method it overrides. It need not throw any exception or can throw subclasses of the exceptions throws by the super class but not anything higher that already thrown by the superclass.

Code The hierarchy in the following code is Throwable class is the superclass and Exception class is the sub class. class Test41 extends Temp { public static void main(String[] args) { Test41 x = new Test41(); x.met1(); } public void met1() throws Throwable { System.out.println("Inside Test41 class"); } } class Temp { public void met1() throws Exception { System.out.println("Inside Temp class"); } }; Output Test41.java:9: met1() in Test41 cannot override met1() in Temp; overridden method does not throw java.lang.Throwable public void met1() throws Throwable ^ 1 error The compiler is trying to tell us that the overridden method is not throwing Throwable and hence the overriding method cannot throw that kind of exception. This is important because Throwable is the superclass of Exception. We can check the same code in the following two ways:

a) Let the overriding method (met1() in Test40 class) not to throw any exception. The code will compile finely because the rule is that the overriding method cannot throw any superclass of the exceptions that what is already thrown by the superclass.

Page 86: Final Unit 1

b) Let the overriding method (met1() in Test40 class) throw RuntimeException which the subclass of Exception. Again the code would compile finely.

Why Overriding? Overriding of methods allows java to support polymorphism, which allows a general class to specify methods that will be common to all of its subclasses, while allowing each of the sub classes to define the specific implementation of some or all of those methods.

Virtual Method Invocation / Dynamic Binding / Runtime Polymorphism / Late Binding To understand the topic of Virtual Method Invocation or also called as Runtime Polymorphism, we should understand when an object of a superclass is allowed to be assigned to the subclass and vice versa. It is possible to automatically allow a sub class instance to be assigned to a super class instance, because the sub class would know all the methods that are there in the super class (because of inheritance). Code class Test42 { public static void main(String[] args) { T1 x = new T1(); T y = new T(); y = x; // subclass variable casted to super class automatically y.met1(); // y.met2(); } } class T { void met1() { System.out.println("Inside met1 in class T"); }

void met3() {

System.out.println("Inside met3 in class T"); }

}; class T1 extends T { void met2() { System.out.println("Inside met2 in class T1");

Page 87: Final Unit 1

} void met1() { System.out.println("Inside met1 in class T1"); } }; Output Inside met1 in class T1 The important points to be noted here are:

a) Here in the above code we see that the compiler automatically allows the sub class instance to be assigned to the superclass instance. That means when we go up the hierarchy there is no need for casting, but when we come down the hierarchy there is a explicit need for casting to avoid compile time error.

b) An important point to note here is that after assignment, when we call a method

which is overridden in the sub class through the assigned instance, it would print the overridden method as above. (e.g. y.met1() in the above example)

c) Comment the instance assignment ( y = x) and then when we call y.met1() it would

print

Inside met1 in class T, this is the method of the super class itself

d) When we do assignment ( y = x) and then try to call the specialized method in the subclass (met2()), the compiler will complain, because when we do assignment (y = x), we are explicitly agreeing that through the assigned instance we can all the methods of the super class only and only the overridden methods in the subclass. (Uncomment y.met2() in the above code and see the error).

Code class Test43 { public static void main(String[] args) { T1 x = new T1(); T y = new T(); x = y; } } class T { void met1() { System.out.println("Inside met1 in class T"); } }; class T1 extends T { void met2()

Page 88: Final Unit 1

{ System.out.println("Inside met2 in class T1"); } void met1() { System.out.println("Inside met1 in class T1"); } }; Output Test43.java:8: incompatible types found : T required: T1 x = y; ^ 1 error Now let us try by casting y to the subclass by typing x = (T1)y; There would not be any compile time error, but when we execute the code, the output would be as under:- java.lang.ClassCastException: T at Test43.main(Test43.java:8) Exception in thread "main" This exception will be thrown to indicate that the code has attempted to cast an object to a subclass of which it is not an instance. We are attempting to cast y in to T1 where it is actually an instance of T. Now let us try casting it to the original class to which it belongs by changing the assignment as x = (T)y;. Even then the output would be Test43.java:8: incompatible types found : T required: T1 x = (T)y; ^ 1 error The Virtual Method invocation is a mechanism by which a call to an overridden function is resolved at run time rather than compile time. How does this happen.

a) A superclass variable can access a subclass object. Java uses this fact to resolve calls to overridden methods at runtime.

b) When a 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 to at the time when the call occurs. Thus this determination is done at runtime.

Page 89: Final Unit 1

c) In other words, it is the type of the object being referred to and not the type of the reference variable.

Code class Test44 extends Temp { int a = 20; void met1() { System.out.println("Inside met1 in class Test44"); } public static void main(String[] args) { Temp x = new Test44(); x.met1(); System.out.println(x.a); } } class Temp { int a = 10; void met1() { System.out.println("Inside met1 in class Temp"); } }; Output Inside met1 in class Test44 10 Now when we are creating a instance till now we have been saying Test x = new Test() only, but here were are saying Temp x = new Test44(), which means that through the instance of the super class we are calling the constructor of the sub class. IMP: We will have to understand that there is a variable a in the super class as well as in the sub class. The variable a in the subclass will be hiding the variable a of the super class, as variables in two classes related through inheritance can only be hidden, whereas the methods will be overridden. Now when we create the instance by saying Temp x = new Test44(), we are creating an instance of the class Temp only and not of Test44 at all. Hence when we say x.a, it prints the value as 10 only. Now when we call x.met1(), it will check whether the method met1() is overridden in the subclass and incase it is, it will call the overridden method of the subclass only and incase it is not overridden, it will call the method of the super class since it is an instance of the super class only. Please note that through the instance x we cannot access any method of the subclass at all. See the revised code for this purpose. Code

Page 90: Final Unit 1

class Test45 extends Temp { int a = 20;

void met1() { System.out.println("Inside met1 in class Test44"); } void met2(); { System.out.println("Inside met2 in class Test44"); } public static void main(String[] args) { Temp x = new Test44(); x.met1(); System.out.println(x.a); x.met2(); // x.met3(); // will throw a compilation error and hence commented. Uncomment to check } } class Temp { int a = 10; void met1() { System.out.println("Inside met1 in class Temp"); } void met3(); { System.out.println("Inside met3 in class Temp"); } }; Output Inside met1 in class Test44 10 Inside met2 in class Temp Here when we say x.met2(), it checks whether the method is overridden in the subclass and incase not it just prints the super class version.

Abstract class

Page 91: Final Unit 1

There are many situations when you want to define a super class that declares the structure of a given abstraction without providing a complete implementation of every method. That is one creates a superclass that only defines a completely general form that will be shares by all of its subclasses leaving it to each of the subclass to fill in the details. For Example, we have a class called Figure which has a method called area () which does nothing, but lets the subclasses like Circle, Triangle, Square to override it and give specific implementation to the same. In this case you should call the area () as abstract. The other example can be a Drawing class. The class contains methods for variety of drawing facilities, but these must be implemented in a platform independent way. You cannot access the video hardware of a machine and still be platform independent. The intention is that the drawing class defines which method should exist, but special platform independent subclasses actually implement that behavior. The syntax of an abstract method is abstract method (); It is important to note here that the abstract method does not have a body. The points to be remember here are:

a) Any class, which has one or more abstract method, should be declared as abstract. To declare a class as abstract, simply use the abstract keyword in front of the class.

b) There can be no objects of the abstract class. That is an abstract class cannot be directly

instantiated with the new keyword. This is so because the class is not complete.

c) Any subclass of an abstract class must override all the abstract methods, or the subclass must also be declared as abstract. That means any subclass must override all of the abstract methods.

d) An abstract class can have a non-abstract method also.

e) An abstract class can have member variables also, which can be used by the subclass

after it overrides the abstract methods.

f) An abstract class need not have any abstract methods, but incase a class has an abstract method, it should mandatorily be declared as abstract class.

Code class Test46 extends Temp { public static void main(String[] args) { Test46 x = new Test46(); x.met1(); x.met2(); x.met3(); } void met1() {

Page 92: Final Unit 1

System.out.println("Overridden met1 in Test46"); } void met3() { System.out.println("Overridden met3 in Test46"); } } abstract class Temp { abstract void met1(); void met2() { System.out.println("Hello World!"); } abstract void met3(); }; Output Overridden met1 in Test46 Hello World! Overridden met3 in Test46 Over here, the class Temp should be declared as abstract class since it has abstract methods. ( try to remove the abstract keyword from the class and then compile the same). Any class (Test46) extending the abstract class should override all the abstract methods or else that class should be declared as abstract since it would have a abstract method by way of inheritance and rule 1 is any class having an abstract method should be declared abstract. (Try commenting the whole method met3() from Test46 and then compile). Try creating an instance of Temp class and compile An abstract class can have non abstract methods also, like met2() in Temp class. An abstract class need not have any abstract methods. We would need a class to be declared as abstract and still not have any abstract methods only in the scenario when we do not want any one to create an instance of our class. Code class Test47 extends Temp { public static void main(String[] args) { Test47 x = new Test47(); x.met1(); } } abstract class Temp

Page 93: Final Unit 1

{ void met1() { System.out.println("Hello World!"); } }; Output Hello World! See in the above class although we are extending the abstract class, since there is no abstract method, we need not override any method and can directly call any other non-abstract methods.

final Keyword The final keyword can be used for a class, variable or a method.

a) When a class is pre-fixed with a final keyword, then that class cannot be extended further. For example, the java.lang.String is a final class. This is done for security reasons, because it ensures that if a method has a reference to a string, it is definitely a string of class String and not a string of a class that is a modified subclass of String that might have been maliciously changed.

b) When a variable is pre-fixed with the final keyword, then it cannot take any other variable

than the variable with which it was initialized. That would mean that it will act like a constant.

c) When a method is pre-fixed with the final keyword, then it cannot be overridden to

provide any additional functionality. This is also done for security reasons. You should make a method final if the method has a implementation that should not be changed and is critical to the consistent state of the object. The methods declared final are sometimes used for optimization. The compiler can generate code that causes direct call to the method rather than the usual virtual method invocation that involves a runtime lookup.

It is a common coding convention to choose all uppercase identifier for final variables. Variables declared as final do not occupy memory on a per instance basis. Thus the final variable is essentially a constant. Thus final keyword is often used to prevent overriding and also to prevent inheritance. Example of final Keyword for a class Code class Test48 extends String { public static void main(String[] args) { System.out.println("Hello World!"); } } Output

Page 94: Final Unit 1

Test48.java:1: cannot inherit from final java.lang.String class Test48 extends String ^ 1 error The above output confirms that we cannot extend classes which are declared as final and all the Wrapper classes and String classes are declared as final in the java API. Examples of final keyword for variables final variables should be initialized when they are declared, which is different from normal class variables which take default value even when they are not initialized. Code class Test50 { final int a; public static void main(String[] args) { Test50 x = new Test50(); x.met1(); } void met1() { System.out.println(a); } } Output Test50.java:1: variable a might not have been initialized class Test50 ^ 1 error This proves the point that final variables should be initialized when they are declared. Code The final variables can be initialized in the constructor of a class also when an instance of the class is created and different instances can take different values of the final variables class Test51 { final int a; Test51(int x) { a = x; } public static void main(String[] args) {

Page 95: Final Unit 1

Test51 l = new Test51(10); Test51 k = new Test51(20); System.out.println(l.a); System.out.println(k.a); // l.a = 40; } } Output 10 20 So here we see that a final variable is initialized in the constructor and can take a single value for different instance. Try removing the comment and then the compiler complains that we cannot change the value of a final variable. Example of final keyword for methods Code class Test49 extends Temp1 { public static void main(String[] args) { System.out.println("Hello World!"); } void met1() { System.out.println("Overridden met1"); } } class Temp1 { final void met1() { System.out.println("final met1"); } }; Output Test49.java:8: met1() in Test49 cannot override met1() in Temp1; overridden method is final void met1() ^ 1 error Here the compiler is complaining that the overridden method is final and final methods cannot be overridden

Inner classes

Page 96: Final Unit 1

Until now we have seen classes defined so far separate from each other. In previous releases, Java supported only top-level classes, which must be members of packages. In the 1.1 release, the Java 1.1 programmer can now define inner classes as members of other classes, locally within a block of statements, or (anonymously) within an expression.

Here are some of the properties that make inner classes useful:

1. The inner class's name is not usable outside its scope, except perhaps in a qualified name. This helps in structuring the classes within a package.

2. The code of an inner class can use simple names from enclosing scopes, including both

class and instance members of enclosing classes, and local variables of enclosing blocks.

It is possible to define a class within another class and such classes are known as nested classes. The scope of the nested class is within the boundary of the outer class. The nested class can access all the variables, including private (since the inner class is within the boundary of the outer class), but the outer class does not have access to the members of the nested class. There are 3 types of inner classes and they are:-

a) Normal Inner Class b) static Inner Class

c) Inner class inside a method.

Normal Inner Class In this case we simply have an inner class declared before closing the final brace of the outer class. The inner class is declared outside any methods but within the outer class Code class Test52 { int a = 10; private int b = 20; public static void main(String[] args) { Test52 x = new Test52(); Test52.Inner y = x.new Inner(); y.met1(); } class Inner { void met1() { System.out.println(a + " "+b); } };

Page 97: Final Unit 1

} Output

10 20 Over here we should remember that to create a instance of the inner class, we mandatorily require an instance of the outer class and then create a instance of the inner class referenced with the outclass class Once the instance of the outer class is created, then we simply call the inner class method. Static Inner Class Inner classes cannot have static declarations of any sort, neither static class variables nor static methods. Code class Test52 { int a = 10; private int b = 20; public static void main(String[] args) { Test52 x = new Test52(); Test52.Inner y = x.new Inner(); y.met1(); } class Inner { static int c = 30; void met1() { System.out.println(a + " "+b+" "+c); } }; } Output Test52.java:14: inner classes cannot have static declarations static int c = 30; ^ 1 error We just changed the code to include a static class variable of the inner class and the compiler complains. To ensure that the inner class shall have static declarations, the whole inner class shall be declared as a static inner class. Remember only inner classes can be static and not outer classes. A major limitation of the static inner classes is that it cannot refer to non-static variables of the outer class

Page 98: Final Unit 1

Code class Test52 { int a = 10; private int b = 20; public static void main(String[] args) { Test52 x = new Test52(); Test52.Inner y = x.new Inner(); y.met1(); } static class Inner { static int c = 30; void met1() { System.out.println(a + " "+b+" "+c); } }; } Output Test52.java:17: non-static variable a cannot be referenced from a static context System.out.println(a + " "+b+" "+c); ^ Test52.java:17: non-static variable b cannot be referenced from a static context System.out.println(a + " "+b+" "+c); ^ 2 errors Hence to compile the above code, either we should remove the variables a and b from the inner class or should declared int a and int b as static in Test52. Another way to create an instance of the inner class is in the following way Test52.Inner y = new Test52().new Inner(); IMP: The class file of Inner will be Test52$Inner.class. Since the system internally uses the $ word, hence we had requested that the $ word to used in a limited way in an identifier. Inner Class inside a method We can also have a inner class inside a method also, but the only condition is that incase the inner class accesses any variable that is inside the method, then that method should be declared as final, or otherwise the compiler will complain. Code class Test53 { public static void main(String[] args) {

Page 99: Final Unit 1

Test x = new Test(); x.met1(); } } class Test { int a = 10; void met1() { int b = 20; class Inner { void met2() { System.out.println("Inside met2"+a+" "+b); } }; // end of inner class Inner x = new Inner(); x.met2(); }// end of met1() };// end of main class Output Test53.java:22: local variable b is accessed from within inner class; needs to be declared final System.out.println("Inside met2"+a+" "+b); ^ 1 error To remove the error , we should make the variable int b as final, since it is accessed inside the Inner class. In the above code we see that we have a inner class inside a method and to call a method of the inner class, we should create a instance of the class and call the method, before getting out of the method itself. Also remember in java forward instantiation is not possible. That is we cannot create an instance before declaring the class itself.

Concept of Packages A package is a collection of class and is often used to keep the class name compartmentalized. The package has both a naming and visibility control mechanism. One can define classes inside a package that is not accessible to others outside the package. Essentially a package is a named collection of classes. To use a package, just use package command as the first statement in the source file. Any classes declared within that file will belong to the specified package.

Page 100: Final Unit 1

If you omit the package statement, the class names are put into the default package with no name. The syntax for the package statement is: package abc // abc is the name of the package IMP: If you want the classes in a package to be accessible outside the package, you must declare the class using the public keyword. The class definitions that aren’t preceded by the public keyword are only accessible from methods in classes that belong to the same package. More than one file can include the same package statement. The package statement simply specifies to which package the classes defined in a file belong. The package mechanism is for two main purposes:

a) Reduce the problems with name conflicts. b) Control the visibility of classes, interfaces and the methods and data defined within them.

One can also have a hierarchy of packages. To do so, simply separate each package name from the one above it by the use of the period. For Example: package abc.xyz.nmq Java uses file systems directories to store packages. For example, a class file for the above class you declare will be a part of the abc package and in a directory called as abc. Remember java is case-sensitive.

Accessing a package How do you access a package when you are compiling a program that uses the package depends on where you have put it. There are a couple of options here. The first but not the best is to leave the .class file for the classes in the package in the directory with the package name. Let’s look at that before we go into to the second option. With the .class file in the original package directly, either the path to your package must appear in the string set for the CLASSPATH environment variable or you must use the classpath option on the command line when you invoke the compiler or the interpreter. This overrides the CLASSPATH environment variable if it happens to be set. Note that it is up to you to make sure that the classes in your package are in the right directory. Java will not prevent you from saving a file in a directory that is quite different from that appearing the package statement. Of the two options here, using the –classpath option on the command line is preferable because it sets the class paths transiently each time and can’t interfere with anything you do subsequently. This has the advantage that it only applies for the current compilation or execution so you can easily set it to suit each run. The command to compile Test.java defining the class path would be: javac –classpath ,; c:\MySource\Test.java

Page 101: Final Unit 1

If you do not set the class path in one of the above two ways or do it incorrectly, then java will not be able to find the classes in any new package you might create. Also we can directly tell the compiler to create a directory with whatever is the package name with the -d option when compiling. This will make the compiler create the directory with the package name and put the .class file inside the created directory. This option is better than manually creating the directory and putting the .class inside the directory as the chances of manual error is there.

The Important java packages are: a) java.applet - Classes for implementing Graphics. b) java.awt - Classes for text, windows and GUIs. c) java.io - Classes for all kinds of input and output d) java.net - Classes for networking. e) java.math - Classes for calculations.

Protected and Default Access Modifiers We had learnt about private and public access modifier and now we will see the other two access modifiers now. Package adds a complete new dimension to access control. Package is a container for classes and other subordinate packages.

Default Modifier A Default Access Modifier means, when we do not specify anything to the class, method or variable it is said to have default access modifier. The default access modifier means it is available to any class inside the package, irrespective of whether it is sub class or not and is not available to any sub class outside the package also. The access modifier from the most restrictive to the least restrictive is private --> default --> protected --> public

Importing packages All of java classes are stored in packages and one would not find a single class just hanging in open air. Since classes within packages must be fully qualified with their package name or names, it would be tedious to type in the long dot-separated package name for every class you want to us. For this java has a special statement called import statements, which will certain class or the entire packages into visibility? The import statement tells the compiler where to find the particular classes.3

Page 102: Final Unit 1

Once imported, a class can be referred to directly, using only its name. The import statement is a convenience to the programmer and is not technically needed to write a complete java program. In a normal java source code, the import statement occurs immediately after the package statement. The general form of a import statement is: import package1.package2.*; This would mean that all the classes in package1.package2 would be imported. But remember it would also take for the basic source java file to compile, as all the classes will have to be imported. If one know a file which is to be specifically imported then it should be written as: import package1.package2.Test; All the standard java classes are included in a basic package called java. The basic language functions are stored in a package inside the java package called java.lang. Normally one will have to import every package or class that you want to use, but since java is useless without much of the functionalities in java.lang, the compiler for all programs implicitly imports it.

protected keyword A Protected Access Modifier is actually a misnomer and is often confusing. By general understanding of the term is seems to be more restrictive that private, but is not actually so. When we declare a member of a class as protected, and then it is available to all members inside the package and also to classes, which is a subclass in a different package. Remember that the protected modifier can be for variables and method only and we cannot declare the class as protected. Now as already learnt there are the two ways in which any variable in one class be accessed in another class

a) by creating an instance and calling the variable with the instance b) by way of inheritance. (the sub class automatically gets all the variables other than

the private one’s) Recap of Access Modifiers

a) private keyword variables and methods are accessible only in the class in which they are declared and not even in the subclasses.

b) default keyword is accessible in the package in which they are declared either by way

of inheritance (in subclass) or (in any other class) by way of creating an instance of the class in which the variable is there.

c) protected modifier is accessible in the package in which they are declared like the

default modifier (by way of inheritance or by creating instance of the class) and also in another package in a class which is a subclass of the class which contains the protected keyword.

Page 103: Final Unit 1

Remember protected keywords are accessible in another packages only in the subclasses, by creating an instance of the subclass and not by creating an instance of the class which contains the protected keyword. Also protected keywords cannot be accessible in other classes in another package by creating an instance of the class in which the protected keyword is there. Also the class which contains the protected keyword should be declared as public.

d) The public keyword variables / methods are accessible everywhere by creating of the

class which contains the public keyword items Now let us have two classes which we will store in two different packages and also try out the protected keyword Code package one; public class Test54 { protected int a = 10; } Now to compile this code we should use the -d option so that the compiler will automatically create a directory by the name of the package (i.e. one) and put Test54.class inside that. Assuming Test54.java is there in c:\java directory, we will go to that directory and type the following command javac -d c:\java Test54.java Over here c:\java specifies that the new directory called as one will be created below c:\java directory. Now to check whether the compiler has done the job we can go the c:\java\one directory and type dir to check the contents of the directory. Now we will create another source code file in another package to access this class variable a. Code package two; import one.*; class Test55 extends Test54 { public static void main(String arg[]) { Test55 x = new Test55(); System.out.println(x.a); } } We will compile the above code also with the -d option as explained earlier.

Page 104: Final Unit 1

Now we need to run the interpreter and we will have to go a directory one above which contains the .class file that is c:\java and type java two.Test55. Output 10 This will print out the value of the class variable in Test54 since Test55 extends Test54.

interfaces We have discussed about the concept of inheritance and have understood that java has simple inheritance only. There are many cases when a particular method will be used by a lot of classes and this can be done by defining them in an interface and all the classes which needs that method will be implementing the interface to provide body to the abstract method. An interface is also like a normal class, but it has only public static and final variable (constants) and public and abstract methods. That would mean that it is similar to abstract classes, but since the interface is by abstract and all the methods are abstract (remember abstract classes can also have non-abstract methods) there is no need to write abstract before the interface. Similarly, all the data members declared in an interface are by default constants, there is no need to explicitly insert a final, static or final modifier before them. But we need to prefix the class name with interface instead of class. For example, the general syntax of an interface is: interface Test { met1(); } implements clause A class declares all of the interfaces it is implementing using the implements clause. The implements clause consists of the keyword implements followed by the list of interfaces separated by commas and it must be put after the extends keyword (if any). This would mean that a class can implement more than one interface. An interface gives the illusion of bending the java technology single inheritance rule, while a class can extend only a single class, it can implement as many interfaces as needed, but it is the duty of that class to mandatorily override all the methods otherwise it should be declared as a abstract class. (since the class has a abstract method which is not overridden). Code interface Temp { int a; void met1(); }

Page 105: Final Unit 1

Output Temp.java:3: = expected int a; ^ 1 error This is because final variable need to be initialized when they are declared. Not to properly run the code have the int a initialized to a value of 10. Code class Test56 implements Temp { public static void main(String[] args) { Test56 x = new Test56(); x.met1(); } public void met1() { a = 20; System.out.println("Inside met1"); } } Output Test56.java:10: cannot assign a value to final variable a a = 20; ^ 1 error The above error proves that all the values in the interfaces are final. Now to properly run the code, remove the line a = 10 and insert a System.out.println (Temp.a) line. The output would be Inside met1 10 This would prove that the variable in the method are static also. Now incase we do not override the method in the interface let us see what happens (for this comment the overriding part) and the output would be Test56.java:1: Test56 should be declared abstract; it does not define met1 () in Test56 class Test56 implements Temp ^ 1 error Interfaces are useful for:

a) Declaring methods that one or more classes are expected to implement.

Page 106: Final Unit 1

b) Determining an object’s programming interface without revealing the actual body of the class.

c) Capturing the similarities between unrelated classes without forcing a class relationship.

Variables in Interfaces One can also use interfaces to import shared constants into multiple classes by simply declaring an interface that contains variables, which are initialized to the desired values. When you then implement the interface all those variable names will be in scope as constants.

Interfaces can be extended One interface can inherit another with the help of the usual extends keyword. When a class implements an interface that inherits another interface, it must provide implementation for all methods defined within the interface inheritance chain.

Partial Implementation It is very much possible that a class will implement an interface, but does not want to override all the abstract method, but will override some abstract methods and leave the further implementation to its own subclasses. In this case we should declare the class as abstract, because there is some abstract method in the class. Code interface Two extends One { void met2(); } interface One { void met1(); } abstract class PartialImplementation implements Two { public void met2() { System.out.println("This is inside met2()"); } } class FullImplementation extends PartialImplementation { public static void main(String[] args) { System.out.println("Hello World!"); } public void met1() {

Page 107: Final Unit 1

System.out.println("This is inside met1"); } } Output class FullImplementation extends PartialImplementation { public static void main(String[] args) { FullImplementation x = new FullImplementation(); x.met1(); x.met2(); } public void met1() { System.out.println("This is inside met1"); } } In the above classes, the PartialImplementation class should be declared as abstract, since it is implementing Interface Two, but does not override all the methods of the interface, that is specifically it does not override met1(). Although met1() is not specifically in Interface Two, it is there in Interface One which Interface Two is extending.

Garbage Collection In the earlier programming languages, it was the duty of the programmer to allocate the memory and also to de-allocate the memory. One of the most frequent reasons for the programs crashes was the lack of the memory, since memory was not released by the objects once their work was finished. In java we do not have that problem at all, since we have a Garbage Collector which always runs in the background when the interpreter is called and automatically re-claims the memory. The only problem is that we cannot force the garage collector nor can we predict at a particular point of time, a object will be definitely garbage collected, since Garbage Collector is a low priority thread. The points to be considered in this sub-module can be summarized as under:-

1. A System Level Thread, which is automatically created by the JVM. 2. Low Priority Thread

3. One cannot predict when the garbage collection of any particular object will be done.

4. One cannot force garbage collection even by using the System.gc() method which will

only request the Garbage Collector to run.

5. By using the finalize() method, there is no guarantee that the object will be immediately collected.

Page 108: Final Unit 1

6. Also we can be sure that when a object is garbage collected, it will definitely call the finalize () method before the object is garbage collected.

finalize method We have already learnt about the concept of Garbage Collection, which is done by a system level thread, which will collect an object, which is of no use. But sometimes an object will need to perform some action when it is destroyed. In many cases a particular java object may be holding some non-java resource such as a window character font etc and we must make it sure that these resources are freed before an object is destroyed. To handle such cases, java has a mechanism called finalization. By using finalization, one can define specific actions that will occur, before the garbage collector reclaims the object. To add a finalize to a class, one needs to just define the finalize method. The Java environment calls that method whenever it is about recycle an object of that class. Inside the finalize () method you specify those actions which must be performed before the object is destroyed. The general form of a finalize () is: protected void finalize() { finalization code; } Here the keyword protected is a specifier that prevents access to finalize () by code defined outside its class. It is important to note here that the method is not called when an object goes out-of-scope. The finalize () method is a member of the Object class. Since all classes inherit from the Object class, your classes also contain the default finalize () method. This gives you an opportunity to execute your special cleanup code on each object before the memory is reclaimed.

native Keyword The native keyword is used to declare native code method. Once declared, these methods can be called from inside your java programs just as you do any other java method. After you declare a native method, you must write the native method and follow a rather complex series of steps to link it with your code. The mechanism used to integrate C code with java programs is called JNI. This methodology was created in 1.1 and then expanded and enhanced in 1.2 The precise steps that you need to follow will vary between different java environments and versions. This also depends on the language that you are using to implement the native method. Native methods seem to offer great promise, because they enable you to gain access to your exiting base of library routines, and they offer the possibility of faster runtime execution. The problems with native methods are:-

Page 109: Final Unit 1

a) Potential security risk: Because a native method executes actual machine

code, it can gain access to any part of the hose system. That is native code is not confined to the JVM and this could allow a virus infection. Applets cannot use native methods.

b) Loss of portability: Because the native code is contained in a DLL, it must

be present on the machine that is executing the java program. Further because each native method is CPU and OS dependent, each DLL is inherently non portable. Thus a java application that uses native methods will be able to run only on a machine for which a compatible DLL has been installed.

Thus the use of native methods should be restricted, because they render you java programs non portable and pose significant security risks.

Methods returning Objects As we know the return type of java method should be some primitive data type or should be specifically declared as void. However methods can also returns object, but care should be taken that there is mandatorily a return statement at the end of the method and the object specified and object returns should be the same. The following example returns a String object, which we capture and print in our program. class ObjectReturn { public static void main(String[] args) { ObjectReturn x = new ObjectReturn(); String s = x.met1(); System.out.println(s); } String met1() { return "Hello"; } } The output would be Hello.

String class A String is a series of characters treated as a single unit. A string may include letters, digits and other various special characters like +,-,@, # etc.

Page 110: Final Unit 1

A white space has no meaning in a java source code, but if included in a String, it is also taken as a character. String is the only object in Java which can be created with out the new keyword and incase it is done so, it is treated as a primitive data type, however when we create String with the new keyword, then it becomes a proper object. Hence the different ways of creating a String are: String s = “Hello”, in which case it is taken as a primitive and stored in the stack, String s1 = new String (“Hello”);, in which case it is taken as a Object properly initialized with the new keyword and stored in the Heap. The 4 Important Constructors of the String class are:-

a) String (String s) – creates an object of the character item passed in the parameters. b) String () – creates an instance of String with no characters in it.

c) String (char c[]) – creates an object of the char array passed into it

d) String (char c[], int startindex, int numberofchars) – This creates an object of the c

array starting from the position in the 2nd parameter till the number of characters as specified in the 3rd parameter.

Code class String1 { public static void main(String[] args) { String s = new String(); String s1 = new String("Hello friends"); char c [] = {'h','e','l','l','o'}; String s2 = new String (c); String s3 = new String(c,0,4); System.out.println(s); System.out.println(s1); System.out.println(s2); System.out.println(s3); } } Output (This is actually a space) Hello friends hello hell The String objects are immutable - their character contents cannot be changed after they are created. A String reference cannot be used to modify a String object to delete or modify a String object from the memory as in other programming languages such as C or C++.

Page 111: Final Unit 1

The Important Methods are:

1. int length () – This returns the number of characters that it contains. 2. char charAt (int index) – To extract a single character at the specified index.

3. boolean equals () – actual contents of the String, which included the case sensitiveness

also. Code class String2 { public static void main(String[] args) { String s = new String("Hello"); String s1 = new String("Hello"); int a = s.length(); char c = s.charAt(1); boolean b = s.equals(s1); System.out.println("The number of characters in s is = "+a); System.out.println("The character at position 1 in s is = "+c); System.out.println("The contents of S and S1 are equal = "+b); } } Output The number of characters in s is = 5 The character at position 1 in s is = e The contents of S and S1 are equal = true

4. boolean equalsIgnoreCase () – checks without the case sensitiveness. 5. boolean startsWith (String s) – Determines if the String starts with the String specified in

the parameter.

6. overloaded version. boolean startsWith (String s, int index) – This allows you to specify a starting point.

Code class String3 { public static void main(String[] args) { String s = new String("hello"); String s1 = new String("HELLO"); boolean a = s.equals(s1);

Page 112: Final Unit 1

boolean b = s.equalsIgnoreCase(s1); boolean c = s1.startsWith("H"); boolean d = s.startsWith("ll",2); System.out.println("Whether s and s1 contents are similar = "+a); System.out.println("Whether s and s1 contents are similar ignoring case = "+b); System.out.println("Whether s starts with h = "+c); System.out.println("Whether s starts with ll from position 2 = "+d); } } Output Whether s and s1 contents are similar = false Whether s and s1 contents are similar ignoring case = true Whether s starts with h = true Whether s starts with ll from position 2 = true

7. int indexOf (int c or String s) – checks for the first occurrence of the character or the string.

8. int lastIndexOf(int c or String s) –

9. overloaded version – int indexOf (int c, int position) – This enables u to start searching

from the specified position.

10. String substring(int startindex) – copies all the characters till the end from the start position in this string to another string.

11. String substring (int start, int end (exclusive)) – copies the characters form the start till the

end into another string. Code class String5 { public static void main(String[] args) { String s = new String ("Hello lilly"); int a = s.indexOf('l'); System.out.println("The first occurence of l in String s is = "+a); int b = s.lastIndexOf('l'); System.out.println("The last occurence of l in String s is = "+b); int c = s.indexOf('l',4); System.out.println("The first occurence of l in String s from position 4 is = "+c); String s1 = s.substring(5); System.out.println("The substring of String s from position 5 is = "+s1); String s2 = s.substring(5,9);

Page 113: Final Unit 1

System.out.println("The substring of String s from position 5 till 9 is = "+s2); } } Output The first occurence of l in String s is = 2 The last occurence of l in String s is = 9 The first occurence of l in String s from position 4 is = 6 The substring of String s from position 5 is = lilly The substring of String s from position 5 till 9 is = lil

12. String replace (char original, char replacement) – replaces the original character with the replacement character in the whole string and returns a new String.

13. String trim () – removes the white space in the beginning and in the end.

14. String toUpperCase () – converts all the characters to Upper Case

15. String toLowerCase() –

16. static String valueOf (any datatype) – returns the String object of any primitive data type.

Code class String6 { public static void main(String[] args) { String s = new String ("Hello"); String s1 = s.replace('l','m'); System.out.println("The new String s1 is = "+s1); String s2 = s1.toUpperCase(); System.out.println("The new String s2 is = "+s2); s2 = s1.toLowerCase(); System.out.println("The String s2 is now = "+s2); String s3 = String.valueOf(10); System.out.println("The new String s3 is = "+s3); } } Output The new String s1 is = Hemmo The new String s2 is = HEMMO The String s2 is now = hemmo The new String s3 is = 10

17. char [] toCharArray() – To convert all the characters in a String to a character array.

Page 114: Final Unit 1

18. boolean regionMatches (int startindex, String 2, int String2start index, int no of characters) – This compares a specific region in a string with another specific region in another String

Code class String7 { public static void main(String[] args) { String s = new String("Gurukul"); char c[] = s.toCharArray(); for (int a = 0;a<c.length;a++ ) { System.out.println(c[a]); } } } Output G u r u k u l Code class String8 { public static void main(String[] args) { String s = new String ("Hello Guys"); String s1 = new String("Girls Hello"); boolean c = s.regionMatches(0,s1,6,4); System.out.println("Whether the position of Hello in s1 and s2 is same = "+c); } } Output Whether the position of Hello in s1 and s2 is same = true Code public class Test83 {

public static void main(String args[]) {

String s1 = new String("Hello");

Page 115: Final Unit 1

String s2 = new String("There"); System.out.println(s1); s1=s2; System.out.println(s1);

} } Output Hello There This is because when we say s1 = s2, the earlier value of s1 is lost and now it points to s2 and hence the output.

StringBuffer Class StringBuffer is a class which is the mutable version for string concatenation. All the methods of the String class return a new string object, as once a string object is created, it cannot be changed. However most of the methods of the StringBuffer class return the same object and changes are made in the same memory location. Constructors

a) StringBuffer () – creates space for 16 characters. b) StringBuffer (int size) – creates a SB with the size specified in the parameter.

c) StringBuffer (String s) – creates a SB with the string specified and additional 16

character spaces. Important Methods 1) int length () – This returns the current length of the SB. 2) int capacity () – This returns the total capacity of the SB. Code class SB1 { public static void main(String[] args) { StringBuffer s = new StringBuffer(); System.out.println("The length of s is = "+s.length()); System.out.println("The total capacity of s is = "+s.capacity()); StringBuffer s1 = new StringBuffer("Hello"); System.out.println("The length of s1 is = "+s1.length()); System.out.println("The total capacity of s1 is = "+s1.capacity()); StringBuffer s2 = new StringBuffer(4); System.out.println("The length of s2 is = "+s2.length());

Page 116: Final Unit 1

System.out.println("The total capacity of s2 is = "+s2.capacity()); } } Output The length of s is = 0 The total capacity of s is = 16 The length of s1 is = 5 The total capacity of s1 is = 21 The length of s2 is = 0 The total capacity of s2 is = 4 3) StringBuffer append (String s): adds to the end of the String Buffer. Is overloaded. 4) StringBuffer insert (int position, String s) – inserts at the specified int position. 5) StringBuffer reverse () – reverses the contents of the String. Code class SB2 { public static void main(String[] args) { StringBuffer s1 = new StringBuffer("Hello"); s1 = s1.append(" Gurukul"); System.out.println("s1 after appending looks like = "+s1); s1 = s1.insert(5," guys from"); System.out.println("s1 after inserting looks like = "+s1); } } Output s1 after appending looks like = Hello Gurukul s1 after inserting looks like = Hello guys from Gurukul 6) StringBuffer delete ( int start , int end ) – Deletes a range of characters. 7) StringBuffer deleteCharAt(int position) – Deletes the character at the specified position. 8) New - StringBuffer replace( int start, int end, String s) – replaces the set of characters

specified between start and end with the String s. 9) New – String substring (int start) – this returns the substring from the StringBuffer object. Code class SB3 { public static void main(String[] args) {

Page 117: Final Unit 1

StringBuffer s1 = new StringBuffer("Hello"); s1.delete(1,3); System.out.println("After deleting characters from 1 to 3 in s1 = "+s1); s1.deleteCharAt(1); System.out.println("After further deleting characters at position 1 in s1 = "+s1); StringBuffer s2 = new StringBuffer("lilly"); s2.replace(1,4,"Hello"); System.out.println("After replacing s2 looks like = "+s2); } } Output After deleting characters from 1 to 3 in s1 = Hlo After further deleting characters at position 1 in s1 = Ho After replacing s2 looks like = lHelloy IMP: Also please note that the equals method is not overridden in the StringBuffer class and hence when we call the equals () method on two String objects, it would return false, although the contents of the same would be true. The same if done with String class would return true, since the equals method is overridden in the String class to check the contents of the String and not the memory location of the objects. Code class Test84 { public static void main(String[] args) { StringBuffer sb = new StringBuffer("One"); StringBuffer sb1= new StringBuffer("One"); boolean a = (sb== sb1); boolean b = sb.equals(sb1); System.out.println(a); System.out.println(b); } } Output false false

What is a Java Exception? Programmers in any language try to always write error and bug free codes, which would execute properly under any circumstances and programs which should never crash. Unfortunately it is not

Page 118: Final Unit 1

only difficult but many times impossible for a code to execute under any circumstances. Any program at a given point of time would execute normally under normal circumstances. In real programs, errors or abnormal conditions occur, either because the programmer didn't anticipate every situation your code would get into (or didn't have the time to test the program enough), or because of situations which are out of the programmer's control - bad input data from users, corrupt files that don't have the right data in them, network connections that don't connect, hardware devices that don't respond. In Java, these sorts of strange events that may cause a program to fail are called Exceptions in general. The term exception is shorthand for the phrase "exceptional event". It can be defined as follows: Definition: An exception is an event that occurs during the execution of a program that disrupts the normal flow of instructions. Many kinds of errors can cause exceptions - problems ranging from serious hardware errors, such as a hard disk crash, to simple programming errors, such as trying to access an out-of-bounds array element. When such an error occurs within a Java method, the method creates an exception object and hands it off to the runtime system. The exception object contains information about the exception, including its type and the state of the program when the error occurred. The runtime system is then responsible for finding some code to handle the error. In Java terminology, creating an exception object and handing it to the runtime system is called throwing an exception. After a method throws an exception, the runtime system checks incase there is so one who can handle that type of exception and incase there is indeed a catch block then the exception is handled properly. The runtime system searches backwards through the call stack, beginning with the method in which the error occurred, until it finds a block that contains an appropriate exception handler or called as the catch block. An exception handler is considered appropriate if the type of the exception thrown is the same as the type of exception handled by the handler. Thus the exception bubbles up (goes up) through the call stack until an appropriate handler is found and one of the calling methods handles the exception. The exception handler chosen is said to catch the exception. If the runtime system exhaustively searches all of the methods on the call stack without finding an appropriate exception handler, the runtime system (and consequently the Java program) terminates. Java defines a number of language features to deal with exceptions, including

1. How to handle exceptions in the code and recover gracefully from potential problems 2. How to tell users of the methods that you're expecting a potential exception

3. How to create an exception if one is necessary.

In other languages that do not support exception handling, errors must be checked and handled manually – typically through the use of error codes and so on.

Page 119: Final Unit 1

This approach is as cumbersome as it is troublesome. Java’s exception handling avoids these problems and in the process brings run time error management into the object oriented world. Java exception handling is managed via five keywords: try, catch, throw, throws and finally.

1. The try statement contains the program statements that you want to monitor for exceptions contained within that block

2. The catch statement handles this exception or throws back the same. The System

generated exceptions are automatically thrown by the java run-time environment.

3. To manually throw an exception we should use the keyword throw

4. Any exception that is thrown out of a method must be specified as such by a throws clause

5. Any code that must be executed before a method returns is put in a finally block

Exception Class Hierarchy All exception types are sub classes of the built in class Throwable. Throwable is at the top of the exception class hierarchy. The Throwable class has two subclasses namely Exception and Error.

The logic behind this partition is why such abnormal conditions happen. Error in programs happens normally not due to any error in programming logic but more due to factors which are outside the programmer control.

The Error subclasses are not expected to be caught under normal circumstance by the program. These abnormal conditions are used by the Java runtime system to indicate errors having to do with the run-time environmental, itself. Error class has subclasses which are serious problems which are not normally associated with the code and which the programmer should not try to catch, like for example ClassFormatError (when the .class file has been tampered with). We should let the JVM handle the Error as the way it wants to.

Exception happens more generally due to factors which are within the programmers control and programmer should properly handle the same. Since the Exception class contains exception sub classes which are within the programmer’s control, the programmer should catch the same (but not all sub classes as explained later on).

The Exception class is again classified into two sections called as the Compile Time Exception and Runtime Exception.

Page 120: Final Unit 1

It is the programmer’s duty to properly handle the Compile Time Exceptions whereas like Errors they can let the JVM handle the Runtime Exception. The RuntimeException automatically defines for the programs that you will write and include things such as division by zero and invalid array indexing.

The other main branch is topped by Error, which defines exceptions that are not expected to be caught under normal circumstances by your program.

Generating Exceptions Whenever there is an exception, it must be caught by an exception handler and dealt with immediately. But incase the same is not caught, and then it 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. The following is the code which automatically generates an exception and on the basis of the output, we will analyze the code

Code class Test57 { public static void main (String args []) { System.out.println("Before Exception"); int a = 42/0; System.out.println("After Exception"); } } Output Before Exception java.lang.ArithmeticException: / by zero at Test57.main(Test57.java:6) Exception in thread "main" When we compile the above code, it compiles properly, but at runtime it generates the following output, which means that ArithmeticException which is generated is a Runtime Exception.

Page 121: Final Unit 1

IMP: Any statement after the exception object in the same block of code will not be printed. When the exception object is raised by the JVM at line number 6 of the above code, it looks for an exception handler immediately and does not find the same and the program crashes. Notice how the class name, Test; the method name, main, the filename, Test.java and the line number 6, are all included in the simple stack trace. Also, notice that the type of the exception thrown is a subclass of Exception called ArithmeticException, which more specifically describes what type of error happened. IMP: The stack trace will always show the sequence of method invocations that led up to the error. Let us see this with the example of a Code Code class Extra3 { public static void main(String[] args) { Extra3 y = new Extra3(); y.met1(); } void met1() { met2(); } void met2() { int a [] = {10,29}; int x = a[3]; System.out.println(x); } } Output java.lang.ArrayIndexOutOfBoundsException at Extra3.met2(Extra3.java:18) at Extra3.met1(Extra3.java:11) at Extra3.main(Extra3.java:6) Exception in thread "main"

try and catch blocks All though the default exception handler provided by the Java runtime system is useful for debugging, you will usually want to handle an exception yourself. Doing so will be advantageous in two ways:-

Page 122: Final Unit 1

a) It allows one to fix the error and allows program to continue b) It prevents the program from terminating automatically. Most users would be confused if

the program stopped running and printed a stack trace whenever an error occurred!. They need to be told in a softer manner and in plain words what caused the above abnormal condition.

try is keyword in java and the block that follows the try should have the codes which the programmer feels that might generate an exception. catch is also keyword in java. The catch block will have in its parameter the type of exception which that particular catch block can handle. Incase if any exception is generated in the try block, the program immediately comes out of the try block and looks for the catch block within the method and incase it does not find the same, it will look for it in the method which called the method in which the abnormal condition happened and this continues till it reaches the topmost method. If the program finds a catch block at any position, then it would continue the normal executed of the program, in the method in which the catch block was found and the program would terminate normally. Code class Extra4 { public static void main(String[] args) { Extra4 y = new Extra4(); y.met1(); System.out.println("last Line in main method"); } void met1() { met2(); System.out.println("last Line in met1()"); } void met2() { int a [] = {10,29}; try { int x = a[3]; } catch (ArrayIndexOutOfBoundsException e) { System.out.println("caught in met2 "); } System.out.println("last Line in met2()"); } } Output

Page 123: Final Unit 1

caught in met2 last Line in met2() last Line in met1() last Line in main method Now instead of having the catch block at the point of generation of the error, let have the catch block in the main method and now let us see the output. Code class Extra5 { public static void main(String[] args) { Extra5 y = new Extra5(); try { y.met1(); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("caught in met2 "); } System.out.println("last Line in main method"); } void met1() { met2(); System.out.println("last Line in met1()"); } void met2() { int a [] = {10,29}; // try // { int x = a[3]; // } /* catch (ArrayIndexOutOfBoundsException e) { System.out.println("caught in met2 "); }*/ System.out.println("last Line in met2()"); } } Output caught in met2 last Line in main method We saw that incase the exception is not caught, it would not print any line further after the generation of the exception and the program would continue further in the method in which it was caught and hence the last lines in met1 and met2 methods were not printed.

Page 124: Final Unit 1

The important points to be noted here is that:

a) Once an exception is thrown, the program control transfers out of the try block into the relevant catch block and any statement after the try block does not execute. We saw that the println statement “In Try Block” did not get executed.

b) Incase a exception is generated in a method, then the program will look for the catch

statement in that method and incase it does not find one, then it will look for the catch statement in the method which called this method and incase again there is no catch block there also, then the program will crash and properly generate the stack records. (We will see this possibility in the next code).

c) Both the try and catch blocks are blocks of code and once the program control shifts out

of the try block, it will not come back into the try block like methods do.

d) A try block must be accompanied by at least one catch statement or finally statement. It is not mandatory that try should always be accompanied with the catch block, it can be with the finally block also, but in that case remember that the exception would not be caught.

e) There can be no intervening statement between the end of a try block and the beginning

of a catch block.

f) A catch statement requires a single formal statement. The argument to a catch statement looks like an argument declaration for a method. The argument type declares the type of exception that the handler can handle and must be the name of a class that inherits from the Throwable class. When a java programs throw an exception they are really just throwing an object and only objects that derive from Throwable can be thrown.

Displaying a Description of an Exception The Throwable class overrides the toString () defined in the object, so that it returns a string containing a description of the exception. You can display this description in a println statement by simply passing the exception as an argument. For Example catch (ArithmeticException e) { System.out.println(“Exception : “ + e); } wherein e gives u the description of the exception that occurred Now there are 4 ways in which to describe an exception in the catch block and they are:-

a) A simple println() method which would say “Exception caught” or some other plain lines, which does not use the exception object e.

b) A printStackTrace () method which uses the exception object and which generated

the complete stack trace as if the exception actually occurred. The printStackTrace() method actually informs us about 5 important things and they are:-

1) The name of the exception. } 2) Message of the exception } Both the above are in the 1st line 3) Method in which exception was generated 4) Source Code file name in which the exception was generated

Page 125: Final Unit 1

5) Line Number in which the exception was generated. The last 3 points are there in the 2nd line. and incase there is no exception handler (catch statement) in a method, they it will go up the stack trace and give details of the same also. (as we saw in the earlier code).

c) Simply printout the exception objects (e). This will give the description of the

exception and the message of the exception ( Line No 1 of the printStackTrace() method) only.

d) Incase we need only the message of the exception, we can use the method

getMessage() on the exception object and get only the message of the exception. Remember that e.getMessage() should be in the println() method.

Code class Extra2 { public static void main(String[] args) { try { int a = 10 / 0; } catch (ArithmeticException e) { System.out.println("Exception caught"); System.out.println("----------------------------------------------"); e.printStackTrace(); System.out.println("---------------------------------"); System.out.println(e); System.out.println("---------------------------------"); System.out.println(e.getMessage()); } } } Output Exception caught ---------------------------------------------- java.lang.ArithmeticException: / by zero at Extra2.main(Extra2.java:7) --------------------------------- java.lang.ArithmeticException: / by zero --------------------------------- / by zero

finally keyword When exceptions are throws, execution in a method takes a rather abrupt, nonlinear path that alters the normal flow through the method. Depending on how the method is coded, it is even possible for an exception to cause the method to return prematurely.

Page 126: Final Unit 1

This could be a problem in some method. For example, if a method opens a file upon entry and closes it upon exit, then you will not want the code that closes the file to be bypassed by the exception-handling mechanism. The finally block provides the means to clean up at the end of executing a try block. You use a finally block when you need to be sure that some particular code is run before a method returns, no matter what exceptions are thrown within the previous try block. A finally block is always executed, regardless of what happened during the execution of the method. If a file needs to be closed or a critical resource released, you can guarantee that it will be done if the code to do it put in a finally block. If an exception is thrown, the finally block will execute even if no catch statement matches the exception. For a try block, either a catch statement or a finally statement has to be present. Code class Test61 { public static void main(String[] args) { int a = 0; int b = 0; try { a = args.length; b = 10/a; System.out.println("The value of b is ="+b); } catch (ArithmeticException e) { e.printStackTrace(); } finally { System.out.println("Finally block"); } System.out.println("After all execution"); } } Output Possibility One Incase we do pass parameters as we did earlier (assume we passed two parameters) then the output would be The value of b is =5 Finally block After all execution

Page 127: Final Unit 1

Possibility Two Incase we do not pass any parameters, then the output would be java.lang.ArithmeticException: / by zero at Test61.main(Test61.java:11) Finally block After all execution In both the possibilities we saw that the finally block was always executed. In the second possibility, we saw that since an exception was generated, it went into the catch block and then into the finally block and the program went on properly. Now let us see what would be the output incase we comment the catch block and the output would be Finally block java.lang.ArithmeticException: / by zero at Test61.main(Test61.java:11) Exception in thread "main" We saw that the finally block gets executed whether the exception is caught or not caught. Over here before the exception stack trace is printed since there is no catch statement, the finally block gets a chance to execute itself and then the error is thrown out. Since there is no catch block, the program gets crashed the final println() statement is not executed.

throws keyword In the previous examples you learned how to deal with methods that might possibly throw exceptions by the Java Run-time system and protecting code (try block) and catching any exceptions that occur. The Java compiler will check to make sure you've somehow dealt with a method's exceptions-but how did it know which exceptions to tell you about in the first place? The answer is that the original method indicated in its signature the exceptions that it might possibly throw. You can use this mechanism in your own methods-in fact; it's good style to do so to make sure that other users of your classes are alerted to the errors your methods may come across. To indicate that a method may possibly throw an exception, you use a special clause in the method definition called throws. The throws Clause To indicate that some code in the body of your method may throw an exception, simply add the throws keyword after the signature for the method (before the opening brace) with the name or names of the exception that your method throws: public boolean myMethod (int x, int y) throws AnException { ... }

Page 128: Final Unit 1

If your method may possibly throw multiple kinds of exceptions, you can put all of them in the throws clause, separated by commas: public boolean myOtherMethod (int x, int y) throws AnException, AnotherException, AThirdException { ... } Note that as with catch you must use a superclass of a group of exceptions to indicate that your method may throw any subclass of that exception: public void YetAnotherMethod() throws IOException { ... } Keep in mind that adding a throws method to your method definition simply means that the method might throw an exception if something goes wrong, not that it actually will. The throws clause simply provides extra information to your method definition about potential exceptions and allows Java to make sure that your method is being used correctly by other people. IMP: Pls remember that the exception which will be caught should be equal or higher in the hierarchy than the exception thrown. Incase it is down in the hierarchy the compiler will complain. Code class Test62 { public static void main(String[] args) { Test62 x = new Test62(); try { x.met1(); } catch (Exception e) { System.out.println("Following Exception caught in main method" + e); } System.out.println("After all exceptions in the main method"); } void met1() throws Exception { try { int a = 10 / 0; } catch (ArithmeticException e) { System.out.println(e.getMessage()); } } }

Page 129: Final Unit 1

Output / by zero After all exceptions in the main method Points to be noted:

1) We are putting int a = 10/0 in a try block within met1() and hence the exception is caught inside met1() itself and no exception is pending and hence it did not go into the catch block in the main method and also printed out the final println () statement.

2) Try removing the try block in met1() method so that an exception object will be

pending and which will be caught in the main method and then the output would be. Following Exception caught in main method java.lang.ArithmeticException: / by zero After all exceptions in the main method

3) Now in the 1st point, there was no exception, but we still put x.met1() code in the try

block as said earlier. We will see now what happens when we remove the try and catch block in the main method and simply put x.met1() in the main method.

Test62.java:8: unreported exception java.lang.Exception; must be caught or declared to be thrown x.met1(); ^ 1 error So here we saw that irrespective of whether an exception comes out the met1() method or not (over here there is no exception since it is already caught in the met1() method) we still have to put the calling code x.met1() in the calling method in try and catch blocks.

4) Now we will change the exception type in the catch block of the main method from

Exception to Arithmetic exception and also remove the full try and catch blocks from met1() so that an Arithmetic exception definitely gets generated and see what is the output.

Test62.java:8: unreported exception java.lang.Exception; must be caught or declared to be thrown x.met1(); ^ 1 error Again the compiler complains, this is because although Arithmetic Exception is coming out, it is declaring to the world that it throws Exception object and all methods which call this method should mandatorily should catch Exception only.

throw keyword Until now we have been depending on the JVM to generate the system defined exception, but in many situations in our code we would want to generate a exception ourselves depending on some conditions.

Page 130: Final Unit 1

Declaring that your method throws an exception is useful only to users of your method and to the Java compiler, which checks to make sure all your exceptions are being dealt with. But the declaration itself doesn't do anything to actually throw that exception should it occur; you have to do that yourself in the body of the method. Remember that exceptions are all instances of some exception class, of which there are many defined in the standard Java class libraries. In order to throw an exception, therefore, you'll need to create a new instance of an exception class. Once you have that instance, use the throw statement to throw it (could this be any easier?). The simplest way to throw an exception is simply like this: throw new ServiceNotAvailableException(); IMP: You can only throw objects that are instances of subclasses of Throwable. This is different from C++ exceptions, which allow you to throw objects of any type. Depending on the exception class you're using, the exception may also have arguments to its constructor that you can use. The most common of these is a string argument, which lets you describe the actual problem in greater detail (which can be very useful for debugging purposes). Here's an example: throw new ServiceNotAvailableException("Exception: service not available, database is offline."); Once an exception is thrown, the method exits immediately, without executing any other code (other than the code inside finally, if that clause exists) and without returning a value. If the calling method does not have a try or catch surrounding the call to your method, the program may very well exit based on the exception you threw. IMP: Whenever a method has a throw keyword inside its body, the signature of the method should mandatorily have the throws keyword. This is but obvious, since throws keyword tell the callers of its method, that a exception might or might not occur from its body and with the throw keyword there is definitely an exception and hence throws is required in the signature of the method. IMP: Like any other case, when an exception object is generated, it would look for the catch block otherwise the program would crash. Also once the exception object is generated, no further statement in the block would be executed. Also the throw keyword can be there in any part of the methods, in the catch block or outside the catch block etc. Code class Test64 { public static void main(String[] args) { Test64 x = new Test64(); try { x.met1(); } catch (Exception e) { System.out.println(e); }

Page 131: Final Unit 1

System.out.println("In the main method"); } void met1() throws Exception { try { int a = 10 / 0; } catch (ArithmeticException e) { System.out.println(e); throw new Exception("This is a user generated exception"); } System.out.println("After the throw keyword"); } } Output java.lang.ArithmeticException: / by zero java.lang.Exception: This is a user generated exception In the main method So here we saw that the first line is because of the catch block in the met1() and there again it uses the throw keyword to generate another Exception object and give it a message. Remember that the println() "After the throw keyword" does not print since there is no catch block for this new exception object and it goes back to the caller, where there is a catch block and the programs continues. IMP: The exception object in the throws cause of the method which has a throw keyword should be higher in the hierarchy always. Incase we swap the exceptions that is the throws keyword would have the ArithmeticException e and the catch block in met1() would have the Exception object, then the following error would be generated Test64.java:28: unreported exception java.lang.Exception; must be caught or declared to be thrown throw new Exception("This is a user generated exception"); ^ 1 error

Checked and Unchecked Exceptions

Since exceptional conditions throw objects, objects are instances of classes, and classes may be inherited in Java, a natural hierarchy can be created which causes exceptions to be grouped in logical ways.

1. Checked Exceptions - The checked exceptions are the exceptions which the java compiler will check and incase not properly done would not compile. The checked exceptions are those classes which are sub-classes of the Exception class other than the RuntimeException class.

Page 132: Final Unit 1

This would mean that for all these subclasses the compiler would check, which would mean that we have to mandatorily write any methods which throw these types of exceptions in try - catch block or the method should have the throws signature. Unless this is done, the compiler will not allow the code to compile

2. Un-checked exceptions- These types of exception are not checked by the compiler and

hence it is not mandatory to write these methods in try / catch block. However to ensure that the program continues smoothly, we should properly handle these exceptions also, but the compiler does not force us, like in the case of Checked Exceptions.All the subclasses of the RuntimeException and Error classes fall under this category.

Exceptions of all Exception classes and subclasses other than RuntimeException which is a subclass of Exception (approximately seventeen different classes plus any that you may add) are checked by the compiler and will result in compiler errors if they are not either caught or specified. Later, we will learn how you can create your own exception classes. Whether your exception objects become non-checked or checked depends on which class you choose as your superclass in defining your exception class. Code import java.io.*; class Test65 { public static void main(String[] args) { try { FileInputStream fis = new FileInputStream("c:/one.txt"); } catch (IOException e) { System.out.println(e); } System.out.println("Hello World!"); } } Output Hello World! The rule is that all checked exceptions should be mandatorily should be put in an exception handling mechanism whether they throw an exception or not. Now in the above code we have put the FileInputStream which throws a FileNotFoundException which is a subclass of the IOException which is a checked exception. We are trying to open a file called one.txt which is there in the C: root directory. For all IO we should use the system independent way of handling the files that is the “/” slash and not the windows type of “\” slash. Now if the file is not there, it would throw an exception and the output would be java.io.FileNotFoundException: c:/one.txt (The system cannot find the file specified) Hello World! Normal Termination

Page 133: Final Unit 1

and if the file is indeed there it would not enter the catch block. Now the argument would be if the file is indeed there then should we put the code in a try - catch block. So let us comment the try and catch statements and directly put the line FileInputStream fis = new FileInputStream("c:/one.txt"); in the main method and the output would be: Test65.java:9: unreported exception java.io.FileNotFoundException; must be caught or declared to be thrown FileInputStream fis = new FileInputStream("c:/one.txt"); ^ 1 error So this confirms that whether in a Checked Exception we should mandatorily put the code in a try - catch block because the compiler checks for the same.

Creating own Exceptions

Exceptions are simply classes, just like any other classes in the Java hierarchy. Although there are a fair number of exceptions in the Java class library that you can use in your own methods, there is a strong possibility that you may want to create your own exceptions to handle different kinds of errors your programs might run into. Fortunately, creating new exceptions is easy. Your new exception should inherit from some other exception in the Java hierarchy. Look for an exception that's close to the one you're creating; for example, an exception for a bad file format would logically be an IOException. If you can't find a closely related exception for your new exception, consider inheriting from Exception, which forms the "top" of the exception hierarchy for explicit exceptions (remember that implicit exceptions, which include subclasses of Error and RuntimeException, inherit from Throwable). Exception classes typically have two constructors: The first takes no arguments and the second takes a single string as an argument. In the latter case you'll want to call super() in that constructor to make sure the string is applied to the right place in the exception. Beyond those three rules, exception classes look just like other classes. You can put them in their own source files and compile them just as you would other classes: IMP: Also the convention is to have the Exception word as the last in the class name of user defined exceptions. Also whether the user defined exception would be a checked exception or unchecked exception would depend on which class we are extending. Code class UserDefinedException1 extends RuntimeException { UserDefinedException1() { } UserDefinedException1(String s) { super(s); } }

Page 134: Final Unit 1

class UserDefinedException extends Exception { UserDefinedException() { } UserDefinedException(String s) { super(s); } } class Test66 { public static void main(String[] args) { Test66 x = new Test66(); try { x.met1(); } catch (Exception e) { System.out.println(e); } } // end of main void met1() throws Exception { if (true) { throw new UserDefinedException1("This is Exception"); } else { throw new UserDefinedException1("This is Exception1"); } } // end of met1 } Output UserDefinedException1: This is Exception In the above code we created two user defined exception and simply tried the same in Test66. Change the if condition to false you will fine that it will throw UserDefinedException1 and the output would be UserDefinedException: This is Exception1 The super statement in the String parameter constructor of the user defined constructor is very important as without that whatever message that we print in the throw statement parameter would not go the getMessage() and hence nothing would be printed. To test the same comment the super() statement from both the user defined exceptions and then compile and run Test66. We will find that whatever message we give the throw statement would not be printed.

Page 135: Final Unit 1

Structure of the IO Package Java input and output is based on the use of streams.

Streams are sequences of bytes that travel from a source to a destination over a communication path. If your program is writing to a stream, it is the stream's source. If it is reading from a stream, it is the stream's destination.

The communication path is dependent on the type of I/O being performed. It can consist of memory-to-memory transfers, file system, network, and other forms of I/O.

A Stream is an abstract representation of an input or output device that is a source of or destination for data. The java.io package supports two types of streams, Binary Streams, which contain binary data, and character streams, which contain character data.

When you write data to a stream as a series of bytes, that is binary data, it is written to the stream exactly as it appears in memory. No transformation of the data takes place. Numerical values are just written as a series of bytes. Character streams are used for storing and retrieving text. You can also use character streams to read a text file not written by a java program.

All numeric values are converted to a textual representation before written to the stream. This involves formatting the data to generate a character representation of the data value.

All Unicode Characters are automatically converted to the local representation of the characters as used by the host machine and then these are written to the file.

Unicode uses 16 bits to represent each character. If the high-order 9 bits are all zeros, then the encoding is simply standard ASCII, otherwise the bits represents a character that is not represented in 7-bit ASCII. Java’s char datatype uses Unicode Encoding.

Unicode’s 16-bit is sufficient to encode most alphabets but pictographic Asian Languages like Japanese, Vietnamese present a problem. The answer for this is UTF (UCS Transformation format and UCS stands for Universal Character Set).

UTF encoding uses as many bits as needed to encode a character: fewer bits for smaller alphabets and more bits for larger Asian alphabets.

The important classes in the io.package are

a) File – An object of this class represents a pathname either to a file that you will access for input or output or to a directory.

b) RandomAccessFile – Random Access to a File.

Page 136: Final Unit 1

c) Output Stream – Base class for Byte Stream output.

d) Input Stream – Base Class for Byte Stream Input.

e) Writer – Base class for Character stream Output.

f) Reader – Base class for Character stream Input. - Streams are powerful because they abstract away the details of the communication path

from input and output operations. This allows all I/O to be performed using a common set of methods.

- Whenever we are using the classes of the java.io package, the package will have to be

imported and all the codes should be put in a try - catch block or the method should have throws signature, because most of the methods in this package throw IOException which is a Checked Exception.

File Class File class represents the name of a file or directory that might exist on the hose machine’s file system. The constructors are

1. File (String file) 2. File(String dir, String subpath)

3. File(File dir, String subpath)

"File" class is a non-stream class because it just has methods to access the information about a file or directory entry in the file system and not the file contents. To get information about a file and perform standard operations on it, we should first have a valid File object. The important methods are:

1. Boolean exists() – Where the file or directory exists or not

2. String getAbsolutePath() – This returns the absolute and not the relative path of file or directory.

3. String getName()

4. String getParent() – This returns the name of the directory that contains the File.

5. Boolean isDirectory()

6. Boolean isFile()

7. String [ ] list() – This returns an array containing the name of files and directories within

the File (which should be a directory).

8. Boolean canRead()

Page 137: Final Unit 1

9. Boolean canWrite()

10. long length()

11. Boolean mkdir(File f)

12. boolean renameTo (File newname) Creating a file or directory createNewFile() - Atomically creates a new, empty file if and only if a file with this name does not yet exist. createTempFile(String prefix, String suffix) - Creates an empty file in the default temporary-file directory, using the given prefix and suffix to generate its name. createTempFile(String prefix, String suffix, File directory) - Creates a new empty file in the specified directory, using the given prefix and suffix strings to generate its name. Creating a File object for a nonexistent file is not an error, so File constructors will not throw any exceptions. You can use the exists() method to find out the file or directory existence. We can create a directory with mkdir() or mkdirs(). mkdir() creates a single directory; mkdirs() creates the directory including any necessary but nonexistent parent directories renaming a file renameTo(File dest) - Renames the file/directory denoted by this abstract pathname. deleting a file or directory delete() to delete a file or directory. Although you can create and delete files and directories, there is no method that allows you to change the current working directory. You have to just create a new "File" object with a different directory for the constructor. IMP: Deleting an instance of the File has no effect on the local file system IMP: Please note that the File class objects created are of a directory present in the system and for checking the same, please change it to a directory present in your system along with the file. Code (Simple methods of the File class) import java.awt.*; import java.awt.event.*; import java.io.*; public class File1 {

Page 138: Final Unit 1

File f; public File1() throws IOException { f= new File("C:/Students-March","test.txt"); System.out.println("Chek for the file " +f.exists()); System.out.println("Chek for the file " +f.getName()); System.out.println("Chek for the file " +f.getParent()); System.out.println("Chek for the file " +f.isFile()); System.out.println("Chek for the file" +f.isDirectory()); } public static void main(String args[]) throws IOException { new File1(); } } Code (Example of the list method of the File class) import java.awt.*; import java.io.*; import java.awt.event.*; public class File2 implements ActionListener { File f; Frame f1; TextArea ta; TextField tf; Button b; public File2() { try { f1 = new Frame("F1"); f1.setLayout(new FlowLayout()); ta = new TextArea(10,20); tf = new TextField(20); b = new Button("Ok"); f1.add(tf); f1.add(b); f1.add(ta); tf.addActionListener(this); b.addActionListener(this); f1.setSize(200,200); f1.setVisible(true); } catch(Exception ie) { ie.printStackTrace(); } }

Page 139: Final Unit 1

public void actionPerformed(ActionEvent ae) { if(ae.getSource()==b) { String s = tf.getText(); File f = new File(s); if (f.isDirectory()) { String arr[]= f.list(); for( int i=0;i<arr.length;i++) { ta.append(""+arr[i]+"\n"); } } else if(f.isFile()) { ta.append("Please enter directory name"); } } } public static void main(String[] args) { new File2(); } }

RandomAccessFile Class One way to ready or modify a file is to use the RandomAccessFile class. This class represents a model of files that is incompatible with the Stream / Writer classes. With a RandomAccessFile, you can seek a desired position within a file and then read or write a desired amount of data. The RandomAccessFile provides method that support seeking, reading and writing Constructors RandomAccessFile (String file, String mode // which can be ‘r’ or ‘rw’) The rw refers to Read - Write over here. The ‘rw” form of constructor is useful when you want to open some of the methods of the File class before opening a RAF, so that a instance of File is in hand when calling the RAF constructor. Constructing a RAF is similar like constructing an instance of File. After a random Access file is created, you can seek to any byte position within the file and then read or write. Pre java systems have supported this seeing to a position relative to the beginning of the file, end of the file or the current position of the file. The methods

Page 140: Final Unit 1

long getFilePointer () throws IOException – This returns the current position within the file, in bytes, Subsequent reading and writing will take place starting at this position. long length() throws – length of file in bytes void seek( long position) thro – This sets the current position within the file in bytes. Subsequent reading and writing will take place at this position. Files start at position 0. The common methods that support reading and writing are: int read() - this returns the next byte from the file or –1 is end of file int read(byte d[]) – attempts to read enough bytes t fill array d[] int read(byte d[], int o, int n) – attempts to read n number of bytes into array d[] starting at o. RandomAccessFile supports reading and writing of all primitive data types. When RAF is no longer needed, it should be closed: void close() throws IOException Code import java.awt.*; import java.io.*; public class Raf1 { RandomAccessFile raf ; public Raf1() { try { raf = new RandomAccessFile("1.txt","rw"); raf.writeBoolean(true); raf.writeChar('a'); raf.writeInt(1234); System.out.println("read1"+raf.length()); raf.seek(1); System.out.println("read1"+raf.readChar()); System.out.println("read1"+raf.readInt()); raf.seek(0); System.out.println("read1"+raf.readBoolean()); } catch(Exception e) { e.printStackTrace(); } } public static void main(String[] args) { new Raf1(); }

Page 141: Final Unit 1

}

Stream Classes The superclass of the Stream Classes or called as the byte oriented classes are the abstract class InputStream and OutputStream. We will be discussing each of the important classes relevant from the certification point over here. FileInputStream This class will enable us to create a InputStream with which one can use to read bytes from a file. The common Constructors are as under: FileInputStream (String filename); FileInputStream (File f); Either of this will throw a checked exception and hence will have to be put in a try / catch block or the method will have to throw this FileNotFoundException. Code import java.io.*; public class Fis1 { public static void main(String[] args) { try { File f =new File(args[0]); FileInputStream fis = new FileInputStream(f); int i = fis.available(); for(int j=0;j<i;j++) { System.out.print((char)fis.read()); } } catch(Exception e) { e.printStackTrace(); } } } Code import java.io.*; public class Fis2 { public static void main(String[] args) {

Page 142: Final Unit 1

try { File f =new File(args[0]); FileInputStream fis = new FileInputStream(f); int i; while((i = fis.read())!=-1) { System.out.print((char)i); } } catch(Exception e) { e.printStackTrace(); } } } In the earlier two codes, we have seen how to use the while and the for loop for using the read () method and then printing out the contents of the file which we pass as argument to the code. ByteArrayInputStream This is an implementation of an InputStream that uses byte array as the source. The two constructors for this are: ByteArrayInputStream (byte b[]) ByteArrayInputStream (byte b[], int start, int noofbytes) Code import java.io.*; public class BAIS { public static void main(String[] args) { try { String s = "hello is it done?"; byte b[] = s.getBytes(); ByteArrayInputStream bais = new ByteArrayInputStream(b); int i; while((i=bais.read())!=-1) { System.out.print((char)i); } } catch (Exception ie) { ie.printStackTrace(); } } }

Page 143: Final Unit 1

SequenceInputStream This class allows us to concatenate two Input Streams. The two constructors for this are: SequenceInputStream (IS one, IS two); Remember it can take only two Input Streams. SequenceInputStream (Enumeration s) In the case of the first constructor, the class reads requests from the first until it runs out and then switches to the other and so on. In the case of Enumeration, it will continue through all the IS until the end of the last one is reached. Code import java.io.*; public class SIS { public static void main(String[] args) { try { FileInputStream fis = new FileInputStream("1.txt"); FileInputStream fis1 = new FileInputStream("2.txt"); SequenceInputStream sis = new SequenceInputStream(fis,fis1); int i; while((i=sis.read())!=-1) { System.out.print((char)i); } } catch (IOException ie) { ie.printStackTrace(); } } } Filter Streams The FilterInputStream and FilterOutputStream classes are subclasses of InputStream and OutputStream that acts just like a regular stream, except that it performs some additional processing on an underlying data stream. Each of the subclasses of FilterInputStream works by wrapping an existing input stream, called the underlying input stream, and providing additional functionality. The methods of FilterInputStream simply override the methods of InputStream with versions that call the corresponding methods of the underlying stream. You won't much use these classes directly. Some of the filtered streams that are:

Page 144: Final Unit 1

1. Buffered streams 2. Data streams 3. Print Stream

You connect filter streams to an underlying stream that supplies the actual bytes of data by passing the original stream to the filter stream's constructor. For example, to create a new DataOutputStream from a FileOutputStream, FileOutputStream fos = new FileOutputStream("ln.txt"); DataOutputStream dos = new DataOutputStream(fos); Buffered Streams Buffering is usually used to increase the efficiency of a stream. The BufferedInputStream is "wrapped" around the underlying stream, a FileInputStream. The first time we call read() on the buffered stream, it fills an internal buffer from the underlying FileInputStream. Subsequent calls to read() return data directly from the buffer, which is faster than reading the file again. The BufferedInputStream constructors let you specify whatever buffer size you want. Data Streams The Date Stream a type of filtered streams is for reading and writing primitive types and objects in a portable way. It gives you access to a range of methods such as readDouble, readInt that will work the same on different platforms. In JDK1.0 this was one of the main ways to access Unicode text, but has been superceded by the Reader classes since JDK 1.1. These classes take an instance of a Stream as a constructor These are conveniently named writeInt(), writeDouble(), writeBoolean(), and so forth. Data written with a DataOutputStream can be read using a DataInputStream using the readInt(), readDouble() and readBoolean() etc. These classes read and write primitive Java data types and Strings in a machine-independent way. (Big-endian for integer types, IEEE-754 for floats and doubles, UTF-8 for Unicode) PrintStream The print stream class is implemented by System.out and System.err. It allows very simple printing of primitive values, objects, and string literals. It uses the platform's default character encoding to convert characters into bytes. This class traps all IOException. However you can test the error status with checkError(). This returns true if an error has occurred, false otherwise. public boolean checkError() The main use of the class is the exceptionally overloaded print() and println() methods. They differ in that println() adds an end-of-line character to whatever it prints while print() does not. Code import java.io.*; public class DIS

Page 145: Final Unit 1

{ public static void main(String[] args) { try { FileOutputStream fos = new FileOutputStream("3.txt"); DataOutputStream dos = new DataOutputStream(fos); dos.writeInt(10) ; dos.writeDouble(10.10); dos.writeBoolean(true); dos.close(); fos.close(); FileInputStream fis = new FileInputStream("3.txt"); DataInputStream dis = new DataInputStream(fis); System.out.println(""+dis.readInt()); System.out.println(""+dis.readDouble()); System.out.println(""+dis.readBoolean()); } catch (IOException ie) { ie.printStackTrace(); } } } FileOutputStream The FileOutputStream is used to create an OutputStream that u can use to write bytes to a file. The most common used constructors are: FileOutputStream (String s) FileOutputStream (File f) FileOutputStream (String s, boolean append) This class can throw IOException or SecurityException. IMP: Creating of a file is not dependent on whether the file is already existing or not. This will create another file and incase there is a existing file, the same will be overwritten. Code import java.io.*; public class FOS1 { public static void main(String[] args) { try { String s= "appending here"; byte b[] =s.getBytes(); FileOutputStream fos = new FileOutputStream("1.txt",true);

Page 146: Final Unit 1

for(int i=0; i<b.length;i++) { fos.write(b[i]); } fos.close(); } catch (IOException ie) { ie.printStackTrace(); } } }

Character Classes The Streams basically was dealing with bytes and hence the Reader and Writer classes was introduced which is also called as Character Oriented Streams. The important Reader Classes from the Certification point of view are

a) File Reader b) BufferedReader

Both the above classes are similar to the byte oriented streams. Code import java.io.*; public class FReader { public static void main(String[] args) { try { FileReader fr= new FileReader("1.txt"); FileWriter fw = new FileWriter("5.txt"); int i; while ((i=fr.read())!=-1) { System.out.print((char)i); } } catch (IOException ie) { ie.printStackTrace(); } } }

Page 147: Final Unit 1

Corresponding to the Reader classes, the important classes from the certification point of view are

a) FileWriter b) BufferedWriter

Code import java.io.*; public class FReader { public static void main(String[] args) { try { FileReader fr= new FileReader("1.txt"); FileWriter fw = new FileWriter("5.txt"); int i; while ((i=fr.read())!=-1) { System.out.print((char)i); } } catch (IOException ie) { ie.printStackTrace(); } } } Code import java.io.*; public class ISReader { public static void main(String[] args) { try { System.out.println("Enter the first number "); BufferedReader br= new BufferedReader(new InputStreamReader(System.in)); String s = br.readLine(); int i =Integer.parseInt(s); System.out.println("Enter the second number "); s = br.readLine(); int j =Integer.parseInt(s);

Page 148: Final Unit 1

int k = i + j; System.out.println("The total is: "+k); } catch (IOException e) { e.printStackTrace(); } } } The above code is important since we are using the System.in to take the input from the user and for this we always have to wrap System.in in the InputStreamReader class.

Multi Threading This is a concept wherein multiple threads within a single process gets executed. When we start a simple program, the default main is a thread and we can also create threads within it. There are two important methods in any thread, that is the run () in which one will put all the codes that the thread will have to execute and another is the start () method, which makes the thread ready to run. When the thread will start running (execute the run ()) will depend on the Thread Scheduler. What the start () does is that it puts the thread in the ready to run state. There are two types of thread schedulers-

Pre-emptive Scheduler: In this case a thread with will leave the running state in the following three situations.

A thread of higher priority is there in the ready to run state.

A thread yields

A thread sleeps.

In Solaris, the scheduling is pre-emptive, that would mean that any thread should either yield or sleep, or the other threads will never run.

Time Sliced Scheduler: In this scheduler any thread runs for a fixed amount of time and then enter the ready to run state and allows another thread to run, again depending of its priority. This scheduler ensure that all thread will run at some stage anyhow. The dis-advantage of this is that it is non-deterministic – which thread executes at a particular point of time or for how long it will execute.

In Windows 98, threads of equal priority are time sliced.

Page 149: Final Unit 1

In java technology, threads are usually preemptive, but not necessarily time sliced (the process of giving each thread an equal amount of CPU time).

The Thread Class and the Runnable Interface

There are two ways how to make a thread execute and that is by extending the Thread Class or by implementing the Runnable Interface. Infact the whole of java’s multithreading system is built upon the Thread class, its methods and its companion interface, Runnable. The main Thread

When a java program starts up, one thread begins running simultaneously. This is usually called the main thread of your program, because it is the one that is executed when your program begins. The main thread is important for two reasons:

It is the thread from which other threads will be spawned. The main thread must be the last thread to finish execution. When the main thread stop, the program stop.

Examples of creating Threads, by extending the Thread Class and by implementing Runnable Interface class Thread1 extends Thread { public static void main(String[] args) { Thread1 x= new Thread1(); x.start(); for (int i=0;i<500;i++) { System.out.println("Main="+i); } } public void run() { for (int j=0;j<500;j++) { System.out.println("Run="+j); } } } class TestThread2 implements Runnable { public static void main(String[] args)

Page 150: Final Unit 1

{ TestThread2 x2 = new TestThread2(); Thread t = new Thread(x2); t.start(); for(int i=0;i<10;i++) { System.out.println("Main = "+i); } } public void run() { for(int j=0;j<10;j++) { System.out.println("Run = "+j); } } }