You can make a class (called a subclass, derived class, or child class) a specialization of another class (called a superclass, base class, or parent class). A subclass inherits the methods and instance data of its superclasses, and is related to its superclasses by an is-a relationship. For example, if subclass P inherits from superclass Q, and subclass Q inherits from superclass S, then an instance of P is an instance of Q and also (by transitivity) an instance of S. An instance of P inherits the methods and data of Q and S. You declare that a class is the subclass of another class within The Class Declaration. For example, suppose that you wanted to create a subclass named SubClass of another class named SuperClass. You would write: class SubClass extends SuperClass { . . . } This declares that SubClass is the subclass of the Superclass class. It also implicitly declares that SuperClass is the superclass of SubClass. A subclass also inherits variables and methods from its superclass's superclass, and so on up the inheritance tree. To simplify our discussion, when this tutorial refers to a class's superclass it means the class's direct ancestor as well as all of its ascendant classes. A Java class can have only one direct superclass. Java does not support multiple inheritance. Creating a subclass can be as simple as including the extends clause in your class declaration. However, you usually have to make other provisions in your code when subclassing a class, such as overriding methods or providing implementation for abstract methods. What Member Variables Does a Subclass Inherit? Rule: A subclass inherits all of the member variables within its superclass that are accessible to that subclass (unless the member variable is hidden by the subclass). The following list itemizes the member variables that are inherited by a subclass: * Subclasses inherit those member variables declared as public or protected. * Subclasses inherit those member variables declared with no access specifier as long as the subclass is in the same package as the superclass. * Subclasses don't inherit a superclass's member variable if the subclass declares a member variable using the same name. The subclass's member variable is said to hide the member variable in the superclass. * Subclasses don't inherit the superclass's private member variables. Hiding Member Variables As mentioned in the previous section, member variables defined in the subclass hide member variables of the same name in the superclass. While this feature of the Java language is powerful and convenient, it can be a fruitful source of errors: hiding a member variable can be done deliberately or by accident. So, when naming your member variables be careful to only hide those member variables that you actually wish to hide. One interesting feature of Java member variables is that a class can access a hidden member variable through its superclass. Consider this superclass and subclass pair: class Super { Number aNumber; } class Sub extends Super { Float aNumber; } The aNumber variable in Sub hides aNumber in Super. But you can access aNumber from the superclass with: super.aNumber super is a Java language keyword that allows a method to refer to hidden variables and overriden methods of the superclass. What Methods Does a Subclass Inherit? The rule that specifies which methods get inherited by a subclass is similar to that for member variables. Rule: A subclass inherits all of the methods within its superclass that are accessible to that subclass (unless the method is overriden by the subclass). The following list itemizes the methods that are inherited by a subclass: * Subclasses inherit those methods declared as public or protected. * Subclasses inherit those superclass methods declared with no access specifier as long as the subclass is in the same package as the superclass. * Subclasses don't inherit a superclass's method if the subclass declares a method using the same name. The method in the subclass is said to override the one in the superclass. * Subclasses don't inherit the superclass's private methods. A subclass can either completely override the implementation for an inherited method, or the subclass can enhance the method by adding functionality to it. Overriding Methods The ability of a subclass to override a method in its superclass allows a class to inherit from a superclass whose behavior is "close enough" and then supplement or modify the behavior of that superclass.
Using the Keyword super Accessing Superclass Members If your method overrides one of its superclass's methods, you can invoke the overridden method through the use of the keyword super. You can also use super to refer to a hidden field (although hiding fields is discouraged). Consider this class, Superclass: public class Superclass { public void printMethod() { System.out.println("Printed in Superclass."); } } Here is a subclass, called Subclass, that overrides printMethod(): public class Subclass extends Superclass { // overrides printMethod in Superclass public void printMethod() { super.printMethod(); System.out.println("Printed in Subclass"); } public static void main(String[] args) { Subclass s = new Subclass(); s.printMethod(); } } Within Subclass, the simple name printMethod() refers to the one declared in Subclass, which overrides the one in Superclass. So, to refer to printMethod() inherited from Superclass, Subclass must use a qualified name, using super as shown. Compiling and executing Subclass prints the following: Printed in Superclass. Printed in Subclass Subclass Constructors The following example illustrates how to use the super keyword to invoke a superclass's constructor. Recall from the Bicycle example that MountainBike is a subclass of Bicycle. Here is the MountainBike (subclass) constructor that calls the superclass constructor and then adds initialization code of its own: public MountainBike(int startHeight, int startCadence, int startSpeed, int startGear) { super(startCadence, startSpeed, startGear); seatHeight = startHeight; } Invocation of a superclass constructor must be the first line in the subclass constructor. The syntax for calling a superclass constructor is super(); or: super(parameter list); super().method; With super(), the superclass no-argument constructor is called. With super(parameter list), the superclass constructor with a matching parameter list is called. Note: If a constructor does not explicitly invoke a superclass constructor, the Java compiler automatically inserts a call to the no-argument constructor of the superclass. If the super class does not have a no-argument constructor, you will get a compile-time error. Object does have such a constructor, so if Object is the only superclass, there is no problem. If a subclass constructor invokes a constructor of its superclass, either explicitly or implicitly, you might think that there will be a whole chain of constructors called, all the way back to the constructor of Object. In fact, this is the case. It is called constructor chaining, and you need to be aware of it when there is a long line of class descent.
class Cuboid extends Rectangle { int length; // shadow variable } class Cuboid extends Rectangle { int length; // shadow variable }
Class VariableBinding java.lang.Object extended by org.snmp4j.smi.VariableBinding All Implemented Interfaces: java.io.Serializable, java.lang.Cloneable, BERSerializable public class VariableBinding extends java.lang.Object implements java.io.Serializable, BERSerializable, java.lang.Cloneable A VariableBinding is an association of a object instance identifier (OID) and the instance's value (Variable). Version: 1.9 Author: Frank Fock See Also: Serialized Form Constructor Summary VariableBinding() Creates a variable binding with a zero length OID and a Null value. VariableBinding(OID oid) Creates a variable binding with the supplied object instance identifier and a Null value. VariableBinding(OID oid, Variable variable) Creates a variable binding with the supplied OID and value. Method Summary java.lang.Object clone() void decodeBER(BERInputStream inputStream) Decodes a Variable from an InputStream. void encodeBER(java.io.OutputStream outputStream) Encodes a Variable to an OutputStream. boolean equals(java.lang.Object o) int getBERLength() Returns the length of this BERSerializable object in bytes when encoded according to the Basic Encoding Rules (BER). int getBERPayloadLength() Returns the length of the payload of this BERSerializable object in bytes when encoded according to the Basic Encoding Rules (BER). OID getOid() Gets the object instance identifier of the variable binding. int getSyntax() Gets the syntax of the variable bindings value. Variable getVariable() Gets the value of the variable binding. int hashCode() boolean isException() Returns whether the variable bindings value has an exception syntax. void setOid(OID oid) Sets the object instance identifier for the variable binding. void setVariable(Variable variable) Sets the value of the variable binding. java.lang.String toString() Gets a string representation of this variable binding using the VariableTextFormat configured by SNMP4JSettings. java.lang.String toValueString() Gets a string representation of this variable binding's value using the VariableTextFormat configured by SNMP4JSettings. Methods inherited from class java.lang.Object finalize, getClass, notify, notifyAll, wait, wait, wait Constructor Detail VariableBinding public VariableBinding() Creates a variable binding with a zero length OID and a Null value. VariableBinding public VariableBinding(OID oid) Creates a variable binding with the supplied object instance identifier and a Null value. Parameters: oid - the OID for the new variable binding. VariableBinding public VariableBinding(OID oid, Variable variable) Creates a variable binding with the supplied OID and value. Parameters: oid - the OID for the new variable binding (must not be null). variable - the value for the new variable binding (must not be null). Method Detail getOid public OID getOid() Gets the object instance identifier of the variable binding. Returns: an OID. setOid public void setOid(OID oid) Sets the object instance identifier for the variable binding. Parameters: oid - an OID (must not be null) that is cloned when added to this binding. setVariable public void setVariable(Variable variable) Sets the value of the variable binding. Parameters: variable - a Variable (must not be null) that is cloned when added to this binding. getVariable public Variable getVariable() Gets the value of the variable binding. Returns: a Variable instance. getSyntax public final int getSyntax() Gets the syntax of the variable bindings value. Returns: a SMI syntax identifier (see SMIConstants). isException public boolean isException() Returns whether the variable bindings value has an exception syntax. Returns: true if the syntax of this variable is an instance of Null and its syntax equals one of the following: * SMIConstants.EXCEPTION_NO_SUCH_OBJECT * SMIConstants.EXCEPTION_NO_SUCH_INSTANCE * SMIConstants.EXCEPTION_END_OF_MIB_VIEW See Also: Variable getBERPayloadLength public final int getBERPayloadLength() Description copied from interface: BERSerializable Returns the length of the payload of this BERSerializable object in bytes when encoded according to the Basic Encoding Rules (BER). Specified by: getBERPayloadLength in interface BERSerializable Returns: the BER encoded length of this variable. getBERLength public final int getBERLength() Description copied from interface: BERSerializable Returns the length of this BERSerializable object in bytes when encoded according to the Basic Encoding Rules (BER). Specified by: getBERLength in interface BERSerializable Returns: the BER encoded length of this variable. decodeBER public final void decodeBER(BERInputStream inputStream) throws java.io.IOException Description copied from interface: BERSerializable Decodes a Variable from an InputStream. Specified by: decodeBER in interface BERSerializable Parameters: inputStream - an InputStream containing a BER encoded byte stream. Throws: java.io.IOException - if the stream could not be decoded by using BER rules. encodeBER public final void encodeBER(java.io.OutputStream outputStream) throws java.io.IOException Description copied from interface: BERSerializable Encodes a Variable to an OutputStream. Specified by: encodeBER in interface BERSerializable Parameters: outputStream - an OutputStream. Throws: java.io.IOException - if an error occurs while writing to the stream. toString public java.lang.String toString() Gets a string representation of this variable binding using the VariableTextFormat configured by SNMP4JSettings. Overrides: toString in class java.lang.Object Returns: a string of the form= . toValueString public java.lang.String toValueString() Gets a string representation of this variable binding's value using the VariableTextFormat configured by SNMP4JSettings. Returns: a string of the form . Since: 1.10 clone public java.lang.Object clone() Overrides: clone in class java.lang.Object hashCode public int hashCode() Overrides: hashCode in class java.lang.Object equals public boolean equals(java.lang.Object o) Overrides: equals in class java.lang.Object
Final classes A final class cannot be subclassed. This is done for reasons of security and efficiency. Accordingly, many of the Java standard library classes are final, for example java.lang.System and java.lang.String. All methods in a final class are implicitly final. Example: public final class MyFinalClass {...} Restricted subclasses are often referred to as "soft final" classes.[1] [edit] Final methods A final method can't be overridden by subclasses. This is used to prevent unexpected behavior from a subclass altering a method that may be crucial to the function or consistency of the class.[2] Example: public class MyClass { public final void myFinalMethod() {...} } A common misconception is that declaring a class or method final improves efficiency by allowing the compiler to directly insert the method inline wherever it is called. In fact the compiler is unable to do this because the method is loaded at runtime and might not be the same version as the one that was just compiled. Only the runtime environment and JIT compiler have the information about exactly which classes have been loaded, and are able to make better decisions about when to inline, whether the method is final or not.[3] [edit] Final variables A final variable can only be initialized once, either via an initializer or an assignment statement. It does not need to be initialized at the point of declaration: this is called a "blank final" variable. A blank final instance variable of a class must be definitely assigned at the end of every constructor of the class in which it is declared; similarly, a blank final static variable must be definitely assigned in a static initializer of the class in which it is declared; otherwise, a compile-time error occurs in both cases. [4] (Note: If the variable is a reference, this means that the variable cannot be re-bound to reference another object. But the object that it references is still mutable, if it was originally mutable.) Unlike the value of a constant, the value of a final variable is not necessarily known at compile time. Example: public class Sphere { public static final double PI = 3.141592653589793; // pi is a universal constant, about as constant as anything can be. public final double radius; public final double xpos; public final double ypos; public final double zpos; Sphere(double x, double y, double z, double r) { radius = r; xpos = x; ypos = y; zpos = z; } [...] } Any attempt to reassign radius, xpos, ypos, or zpos will meet with a compile error. In fact, even if the constructor doesn't set a final variable, attempting to set it outside the constructor will result in a compilation error. To illustrate that finality doesn't guarantee immutability: suppose we replace the three position variables with a single one: public final Position pos; where pos is an object with three properties pos.x, pos.y and pos.z. Then pos cannot be assigned to, but the three properties can, unless they are final themselves. Like full immutability, finality of variables has great advantages, especially in optimization. For instance, Sphere will probably have a function returning its volume; knowing that its radius is constant allows us to memoize the computed volume. If we have relatively few Spheres and we need their volumes very often, the performance gain might be substantial. Making the radius of a Sphere final informs developers and compilers that this sort of optimization is possible in all code that uses Spheres.
An abstract class is a class that is declared abstract—it may or may not include abstract methods. Abstract classes cannot be instantiated, but they can be subclassed. An abstract method is a method that is declared without an implementation (without braces, and followed by a semicolon), like this: abstract void moveTo(double deltaX, double deltaY); If a class includes abstract methods, the class itself must be declared abstract, as in: public abstract class GraphicObject { // declare fields // declare non-abstract methods abstract void draw(); } When an abstract class is subclassed, the subclass usually provides implementations for all of the abstract methods in its parent class. However, if it does not, the subclass must also be declared abstract. Note: All of the methods in an interface (see the Interfaces section) are implicitly abstract, so the abstract modifier is not used with interface methods (it could be—it's just not necessary). Abstract Classes versus Interfaces Unlike interfaces, abstract classes can contain fields that are not static and final, and they can contain implemented methods. Such abstract classes are similar to interfaces, except that they provide a partial implementation, leaving it to subclasses to complete the implementation. If an abstract class contains only abstract method declarations, it should be declared as an interface instead. Multiple interfaces can be implemented by classes anywhere in the class hierarchy, whether or not they are related to one another in any way. Think of Comparable or Cloneable, for example. By comparison, abstract classes are most commonly subclassed to share pieces of implementation. A single abstract class is subclassed by similar classes that have a lot in common (the implemented parts of the abstract class), but also have some differences (the abstract methods). An Abstract Class Example In an object-oriented drawing application, you can draw circles, rectangles, lines, Bezier curves, and many other graphic objects. These objects all have certain states (for example: position, orientation, line color, fill color) and behaviors (for example: moveTo, rotate, resize, draw) in common. Some of these states and behaviors are the same for all graphic objects—for example: position, fill color, and moveTo. Others require different implementations—for example, resize or draw. All GraphicObjects must know how to draw or resize themselves; they just differ in how they do it. This is a perfect situation for an abstract superclass. You can take advantage of the similarities and declare all the graphic objects to inherit from the same abstract parent object—for example, GraphicObject, as shown in the following figure. Classes Rectangle, Line, Bezier, and Circle inherit from GraphicObject Classes Rectangle, Line, Bezier, and Circle inherit from GraphicObject First, you declare an abstract class, GraphicObject, to provide member variables and methods that are wholly shared by all subclasses, such as the current position and the moveTo method. GraphicObject also declares abstract methods for methods, such as draw or resize, that need to be implemented by all subclasses but must be implemented in different ways. The GraphicObject class can look something like this: abstract class GraphicObject { int x, y; ... void moveTo(int newX, int newY) { ... } abstract void draw(); abstract void resize(); } Each non-abstract subclass of GraphicObject, such as Circle and Rectangle, must provide implementations for the draw and resize methods: class Circle extends GraphicObject { void draw() { ... } void resize() { ... } } class Rectangle extends GraphicObject { void draw() { ... } void resize() { ... } } When an Abstract Class Implements an Interface In the section on Interfaces, it was noted that a class that implements an interface must implement all of the interface's methods. It is possible, however, to define a class that does not implement all of the interface methods, provided that the class is declared to be abstract. For example, abstract class X implements Y { // implements all but one method of Y } class XX extends X { // implements the remaining method in Y } In this case, class X must be abstract because it does not fully implement Y, but class XX does, in fact, implement Y. Class Members An abstract class may have static fields and static methods. You can use these static members with a class reference—for example, AbstractClass.staticMethod()—as you would with any other class.
An interface is a collection of abstract methods. A class implements an interface, thereby inheriting the abstract methods of the interface. An interface is not a class. Writing an interface is similar to writing a class, but they are two different concepts. A class describes the attributes and behaviors of an object. An interface contains behaviors that a class implements. Unless the class that implements the interface is abstract, all the methods of the interface need to be defined in the class. An interface is similar to a class in the following ways: An interface can contain any number of methods. An interface is written in a file with a .java extension, with the name of the interface matching the name of the file. The bytecode of an interface appears in a .class file. Interfaces appear in packages, and their corresponding bytecode file must be in a directory structure that matches the package name. However, an interface is different from a class in several ways, including: You cannot instantiate an interface. An interface does not contain any constructors. All of the methods in an interface are abstract. An interface cannot contain instance fields. The only fields that can appear in an interface must be declared both static and final. An interface is not extended by a class; it is implemented by a class. An interface can extend multiple interfaces. Declaring Interfaces: The interface keyword is used to declare an interface. Here is a simple example to declare an interface: Example: Let us look at an example that depicts encapsulation: /* File name : NameOfInterface.java */ import java.lang.*; //Any number of import statements public interface NameOfInterface { //Any number of final, static fields //Any number of abstract method declarations\ } Interfaces have the following properties: An interface is implicitly abstract. You do not need to use the abstract keyword when declaring an interface. Each method in an interface is also implicitly abstract, so the abstract keyword is not needed. Methods in an interface are implicitly public. Example: /* File name : Animal.java */ interface Animal { public void eat(); public void travel(); } Implementing Interfaces: When a class implements an interface, you can think of the class as signing a contract, agreeing to perform the specific behaviors of the interface. If a class does not perform all the behaviors of the interface, the class must declare itself as abstract. Aclass uses the implements keyword to implement an interface. The implements keyword appears in the class declaration following the extends portion of the declaration. /* File name : MammalInt.java */ public class MammalInt implements Animal{ public void eat(){ System.out.println("Mammal eats"); } public void travel(){ System.out.println("Mammal travels"); } public int noOfLegs(){ return 0; } public static void main(String args[]){ MammalInt m = new MammalInt(); m.eat(); m.travel(); } } This would produce following result: Mammal eats Mammal travels When overriding methods defined in interfaces there are several rules to be followed: Checked exceptions should not be declared on implementation methods other than the ones declared by the interface method or subclasses of those declared by the interface method. The signature of the interface method and the same return type or subtype should be maintained when overriding the methods. An implementation class itself can be abstract and if so interface methods need not be implemented. When implementation interfaces there are several rules: A class can implement more than one interface at a time. A class can extend only one class, but implement many interface. An interface can extend another interface, similarly to the way that a class can extend another class. Extending Interfaces: An interface can extend another interface, similarly to the way that a class can extend another class. The extends keyword is used to extend an interface, and the child interface inherits the methods of the parent interface. The following Sports interface is extended by Hockey and Football interfaces. //Filename: Sports.java public interface Sports { public void setHomeTeam(String name); public void setVisitingTeam(String name); } //Filename: Football.java public interface Football extends Sports { public void homeTeamScored(int points); public void visitingTeamScored(int points); public void endOfQuarter(int quarter); } //Filename: Hockey.java public interface Hockey extends Sports { public void homeGoalScored(); public void visitingGoalScored(); public void endOfPeriod(int period); public void overtimePeriod(int ot); } The Hockey interface has four methods, but it inherits two from Sports; thus, a class that implements Hockey needs to implement all six methods. Similarly, a class that implements Football needs to define the three methods from Football and the two methods from Sports.
The Object class, in the java.lang package, sits at the top of the class hierarchy tree. Every class is a descendant, direct or indirect, of the Object class. Every class you use or write inherits the instance methods of Object. You need not use any of these methods, but, if you choose to do so, you may need to override them with code that is specific to your class. The methods inherited from Object that are discussed in this section are: protected Object clone() throws CloneNotSupportedException Creates and returns a copy of this object. public boolean equals(Object obj) Indicates whether some other object is "equal to" this one. protected void finalize() throws Throwable Called by the garbage collector on an object when garbage collection determines that there are no more references to the object public final Class getClass() Returns the runtime class of an object. public int hashCode() Returns a hash code value for the object. public String toString() Returns a string representation of the object. The notify, notifyAll, and wait methods of Object all play a part in synchronizing the activities of independently running threads in a program, which is discussed in a later lesson and won't be covered here. There are five of these methods: public final void notify() public final void notifyAll() public final void wait() public final void wait(long timeout) public final void wait(long timeout, int nanos) Note: There are some subtle aspects to a number of these methods, especially the clone method. The clone() Method If a class, or one of its superclasses, implements the Cloneable interface, you can use the clone() method to create a copy from an existing object. To create a clone, you write: aCloneableObject.clone(); Object's implementation of this method checks to see whether the object on which clone() was invoked implements the Cloneable interface. If the object does not, the method throws a CloneNotSupportedException exception. Exception handling will be covered in a later lesson. For the moment, you need to know that clone() must be declared as protected Object clone() throws CloneNotSupportedException or: public Object clone() throws CloneNotSupportedException if you are going to write a clone() method to override the one in Object. If the object on which clone() was invoked does implement the Cloneable interface, Object's implementation of the clone() method creates an object of the same class as the original object and initializes the new object's member variables to have the same values as the original object's corresponding member variables. The simplest way to make your class cloneable is to add implements Cloneable to your class's declaration. then your objects can invoke the clone() method. For some classes, the default behavior of Object's clone() method works just fine. If, however, an object contains a reference to an external object, say ObjExternal, you may need to override clone() to get correct behavior. Otherwise, a change in ObjExternal made by one object will be visible in its clone also. This means that the original object and its clone are not independent—to decouple them, you must override clone() so that it clones the object and ObjExternal. Then the original object references ObjExternal and the clone references a clone of ObjExternal, so that the object and its clone are truly independent. The equals() Method The equals() method compares two objects for equality and returns true if they are equal. The equals() method provided in the Object class uses the identity operator (==) to determine whether two objects are equal. For primitive data types, this gives the correct result. For objects, however, it does not. The equals() method provided by Object tests whether the object references are equal—that is, if the objects compared are the exact same object. To test whether two objects are equal in the sense of equivalency (containing the same information), you must override the equals() method. Here is an example of a Book class that overrides equals(): public class Book { ... public boolean equals(Object obj) { if (obj instanceof Book) return ISBN.equals((Book)obj.getISBN()); else return false; } } Consider this code that tests two instances of the Book class for equality: // Swing Tutorial, 2nd edition Book firstBook = new Book("0201914670"); Book secondBook = new Book("0201914670"); if (firstBook.equals(secondBook)) { System.out.println("objects are equal"); } else { System.out.println("objects are not equal"); } This program displays objects are equal even though firstBook and secondBook reference two distinct objects. They are considered equal because the objects compared contain the same ISBN number. You should always override the equals() method if the identity operator is not appropriate for your class. Note: If you override equals(), you must override hashCode() as well. The finalize() Method The Object class provides a callback method, finalize(), that may be invoked on an object when it becomes garbage. Object's implementation of finalize() does nothing—you can override finalize() to do cleanup, such as freeing resources. The finalize() method may be called automatically by the system, but when it is called, or even if it is called, is uncertain. Therefore, you should not rely on this method to do your cleanup for you. For example, if you don't close file descriptors in your code after performing I/O and you expect finalize() to close them for you, you may run out of file descriptors. The getClass() Method You cannot override getClass. The getClass() method returns a Class object, which has methods you can use to get information about the class, such as its name (getSimpleName()), its superclass (getSuperclass()), and the interfaces it implements (getInterfaces()). For example, the following method gets and displays the class name of an object: void printClassName(Object obj) { System.out.println("The object's" + " class is " + obj.getClass().getSimpleName()); } The Class class, in the java.lang package, has a large number of methods (more than 50). For example, you can test to see if the class is an annotation (isAnnotation()), an interface (isInterface()), or an enumeration (isEnum()). You can see what the object's fields are (getFields()) or what its methods are (getMethods()), and so on. The hashCode() Method The value returned by hashCode() is the object's hash code, which is the object's memory address in hexadecimal. By definition, if two objects are equal, their hash code must also be equal. If you override the equals() method, you change the way two objects are equated and Object's implementation of hashCode() is no longer valid. Therefore, if you override the equals() method, you must also override the hashCode() method as well. The toString() Method You should always consider overriding the toString() method in your classes. The Object's toString() method returns a String representation of the object, which is very useful for debugging. The String representation for an object depends entirely on the object, which is why you need to override toString() in your classes. You can use toString() along with System.out.println() to display a text representation of an object, such as an instance of Book: System.out.println(firstBook.toString()); which would, for a properly overridden toString() method, print something useful, like this: ISBN: 0201914670; The Swing Tutorial; A Guide to Constructing GUIs, 2nd Edition
The types that comprise a package are known as the package members. To use a public package member from outside its package, you must do one of the following: Refer to the member by its fully qualified name Import the package member Import the member's entire package Each is appropriate for different situations, as explained in the sections that follow. Referring to a Package Member by Its Qualified Name So far, most of the examples in this tutorial have referred to types by their simple names, such as Rectangle and StackOfInts. You can use a package member's simple name if the code you are writing is in the same package as that member or if that member has been imported. However, if you are trying to use a member from a different package and that package has not been imported, you must use the member's fully qualified name, which includes the package name. Here is the fully qualified name for the Rectangle class declared in the graphics package in the previous example. graphics.Rectangle You could use this qualified name to create an instance of graphics.Rectangle: graphics.Rectangle myRect = new graphics.Rectangle(); Qualified names are all right for infrequent use. When a name is used repetitively, however, typing the name repeatedly becomes tedious and the code becomes difficult to read. As an alternative, you can import the member or its package and then use its simple name. Importing a Package Member To import a specific member into the current file, put an import statement at the beginning of the file before any type definitions but after the package statement, if there is one. Here's how you would import the Rectangle class from the graphics package created in the previous section. import graphics.Rectangle; Now you can refer to the Rectangle class by its simple name. Rectangle myRectangle = new Rectangle(); This approach works well if you use just a few members from the graphics package. But if you use many types from a package, you should import the entire package. Importing an Entire Package To import all the types contained in a particular package, use the import statement with the asterisk (*) wildcard character. import graphics.*; Now you can refer to any class or interface in the graphics package by its simple name. Circle myCircle = new Circle(); Rectangle myRectangle = new Rectangle(); The asterisk in the import statement can be used only to specify all the classes within a package, as shown here. It cannot be used to match a subset of the classes in a package. For example, the following does not match all the classes in the graphics package that begin with A. // does not work import graphics.A*; Instead, it generates a compiler error. With the import statement, you generally import only a single package member or an entire package. Note: Another, less common form of import allows you to import the public nested classes of an enclosing class. For example, if the graphics.Rectangle class contained useful nested classes, such as Rectangle.DoubleWide and Rectangle.Square, you could import Rectangle and its nested classes by using the following two statements. import graphics.Rectangle; import graphics.Rectangle.*; Be aware that the second import statement will not import Rectangle. Another less common form of import, the static import statement, will be discussed at the end of this section. For convenience, the Java compiler automatically imports three entire packages for each source file: (1) the package with no name, (2) the java.lang package, and (3) the current package (the package for the current file). Apparent Hierarchies of Packages At first, packages appear to be hierarchical, but they are not. For example, the Java API includes a java.awt package, a java.awt.color package, a java.awt.font package, and many others that begin with java.awt. However, the java.awt.color package, the java.awt.font package, and other java.awt.xxxx packages are not included in the java.awt package. The prefix java.awt (the Java Abstract Window Toolkit) is used for a number of related packages to make the relationship evident, but not to show inclusion. Importing java.awt.* imports all of the types in the java.awt package, but it does not import java.awt.color, java.awt.font, or any other java.awt.xxxx packages. If you plan to use the classes and other types in java.awt.color as well as those in java.awt, you must import both packages with all their files: import java.awt.*; import java.awt.color.*; Name Ambiguities If a member in one package shares its name with a member in another package and both packages are imported, you must refer to each member by its qualified name. For example, the graphics package defined a class named Rectangle. The java.awt package also contains a Rectangle class. If both graphics and java.awt have been imported, the following is ambiguous. Rectangle rect; In such a situation, you have to use the member's fully qualified name to indicate exactly which Rectangle class you want. For example, graphics.Rectangle rect; The Static Import Statement There are situations where you need frequent access to static final fields (constants) and static methods from one or two classes. Prefixing the name of these classes over and over can result in cluttered code. The static import statement gives you a way to import the constants and static methods that you want to use so that you do not need to prefix the name of their class. The java.lang.Math class defines the PI constant and many static methods, including methods for calculating sines, cosines, tangents, square roots, maxima, minima, exponents, and many more. For example, public static final double PI = 3.141592653589793; public static double cos(double a) { ... } Ordinarily, to use these objects from another class, you prefix the class name, as follows. double r = Math.cos(Math.PI * theta); You can use the static import statement to import the static members of java.lang.Math so that you don't need to prefix the class name, Math. The static members of Math can be imported either individually: import static java.lang.Math.PI; or as a group: import static java.lang.Math.*; Once they have been imported, the static members can be used without qualification. For example, the previous code snippet would become: double r = cos(PI * theta); Obviously, you can write your own classes that contain constants and static methods that you use frequently, and then use the static import statement. For example, import static mypackage.MyConstants.*; Java Static Import First lets understand what does “java import” does to your java program! Consider the java import statements: 1) import package.ClassA; 2) import package.*; Java statement (1) gives you a license to use ClassA inside the whole program without the package reference. That is you can use like ClassA obj = new ClassA(); or ClassA.getStatic(); Java statement (2) allows you to use all the java classes that belong the imported package in the above manner. That is without the package reference. If you don’t use import statement, you can still use the classes of that package. But you should invoke it with package reference whereever you use. That is like, package.ClassA obj = new package.ClassA(); – looks very ugly isn’t it? Now coming to the static import part. Like the above ugly line we have been unknowingly using (abusing) the java static feature. Consider the java example: double r = Math.cos(Math.PI * theta); How about writing the same java code like: double r = cos(PI * theta); – looks more readable right? This is where static import in java comes to help you. import static java.lang.Math.PI; import static java.lang.Math.cos; Do the above static imports and then you can write it in the more readable way! Java Static Import The normal import declaration imports classes from packages, so that they can be used without package reference. Similarly the static import declaration imports static members from classes and allowing them to be used without class reference. Now, we have got an excellent java feature from java 1.5. Ok now we shall see how we can abuse this! Can i static import everything? like, import static java.lang.Math.*; – yes it is allowed! Similarly you do for class import. Please don’t use this feature, because over a period you may not understand which static method or static attribute belongs to which class inside the java program. The program may become unreadable. General guidelines to use static java import: 1) Use it to declare local copies of java constants 2) When you require frequent access to static members from one or two java classes
This section explains how to use the PATH and CLASSPATH environment variables on Microsoft Windows, Solaris, and Linux. Consult the installation instructions included with your installation of the Java Development Kit (JDK) software bundle for current information. After installing the software, the JDK directory will have the structure shown below. JDK directory structure The bin directory contains both the compiler and the launcher. Update the PATH Environment Variable (Microsoft Windows) You can run Java applications just fine without setting the PATH environment variable. Or, you can optionally set it as a convenience. Set the PATH environment variable if you want to be able to conveniently run the executables (javac.exe, java.exe, javadoc.exe, and so on) from any directory without having to type the full path of the command. If you do not set the PATH variable, you need to specify the full path to the executable every time you run it, such as: C:\Java\jdk1.7.0\bin\javac MyClass.java The PATH environment variable is a series of directories separated by semicolons (;). Microsoft Windows looks for programs in the PATH directories in order, from left to right. You should have only one bin directory for the JDK in the path at a time (those following the first are ignored), so if one is already present, you can update that particular entry. The following is an example of a PATH environment variable: C:\Java\jdk1.7.0\bin;C:\Windows\System32\;C:\Windows\;C:\Windows\System32\Wbem It is useful to set the PATH environment variable permanently so it will persist after rebooting. To make a permanent change to the PATH variable, use the System icon in the Control Panel. The precise procedure varies depending on the version of Windows: Windows XP Select Start, select Control Panel. double click System, and select the Advanced tab. Click Environment Variables. In the section System Variables, find the PATH environment variable and select it. Click Edit. If the PATH environment variable does not exist, click New. In the Edit System Variable (or New System Variable) window, specify the value of the PATH environment variable. Click OK. Close all remaining windows by clicking OK. Windows Vista: From the desktop, right click the My Computer icon. Choose Properties from the context menu. Click the Advanced tab (Advanced system settings link in Vista). Click Environment Variables. In the section System Variables, find the PATH environment variable and select it. Click Edit. If the PATH environment variable does not exist, click New. In the Edit System Variable (or New System Variable) window, specify the value of the PATH environment variable. Click OK. Close all remaining windows by clicking OK. Windows 7: From the desktop, right click the Computer icon. Choose Properties from the context menu. Click the Advanced system settings link. Click Environment Variables. In the section System Variables, find the PATH environment variable and select it. Click Edit. If the PATH environment variable does not exist, click New. In the Edit System Variable (or New System Variable) window, specify the value of the PATH environment variable. Click OK. Close all remaining windows by clicking OK. Note: You may see a PATH environment variable similar to the following when editing it from the Control Panel: %JAVA_HOME%\bin;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem Variables enclosed in percentage signs (%) are existing environment variables. If one of these variables is listed in the Environment Variables window from the Control Panel (such as JAVA_HOME), then you can edit its value. If it does not appear, then it is a special environment variable that the operating system has defined. For example, SystemRoot is the location of the Microsoft Windows system folder. To obtain the value of a environment variable, enter the following at a command prompt. (This example obtains the value of the SystemRoot environment variable): echo %SystemRoot% Update the PATH Variable (Solaris and Linux) You can run the JDK just fine without setting the PATH variable, or you can optionally set it as a convenience. However, you should set the path variable if you want to be able to run the executables (javac, java, javadoc, and so on) from any directory without having to type the full path of the command. If you do not set the PATH variable, you need to specify the full path to the executable every time you run it, such as: % /usr/local/jdk1.7.0/bin/javac MyClass.java To find out if the path is properly set, execute: % java -version This will print the version of the java tool, if it can find it. If the version is old or you get the error java: Command not found, then the path is not properly set. To set the path permanently, set the path in your startup file. For C shell (csh), edit the startup file (~/.cshrc): set path=(/usr/local/jdk1.7.0/bin ) For bash, edit the startup file (~/.bashrc): PATH=/usr/local/jdk1.7.0/bin: export PATH For ksh, the startup file is named by the environment variable, ENV. To set the path: PATH=/usr/local/jdk1.7.0/bin: export PATH For sh, edit the profile file (~/.profile): PATH=/usr/local/jdk1.7.0/bin: export PATH Then load the startup file and verify that the path is set by repeating the java command: For C shell (csh): % source ~/.cshrc % java -version For ksh, bash, or sh: % . /.profile % java -version Checking the CLASSPATH variable (All platforms) The CLASSPATH variable is one way to tell applications, including the JDK tools, where to look for user classes. (Classes that are part of the JRE, JDK platform, and extensions should be defined through other means, such as the bootstrap class path or the extensions directory.) The preferred way to specify the class path is by using the -cp command line switch. This allows the CLASSPATH to be set individually for each application without affecting other applications. Setting the CLASSPATH can be tricky and should be performed with care. The default value of the class path is ".", meaning that only the current directory is searched. Specifying either the CLASSPATH variable or the -cp command line switch overrides this value. To check whether CLASSPATH is set on Microsoft Windows NT/2000/XP, execute the following: C:> echo %CLASSPATH% On Solaris or Linux, execute the following: % echo $CLASSPATH If CLASSPATH is not set you will get a CLASSPATH: Undefined variable error (Solaris or Linux) or simply %CLASSPATH% (Microsoft Windows NT/2000/XP). To modify the CLASSPATH, use the same procedure you used for the PATH variable. Class path wildcards allow you to include an entire directory of .jar files in the class path without explicitly naming them individually. For more information, including an explanation of class path wildcards, and a detailed description on how to clean up the CLASSPATH environment variable, see the Setting the Class Path technical note.
One of the techniques in object-oriented programming is encapsulation. It concerns the hiding of data in a class and making this class available only through methods. In this way the chance of making accidental mistakes in changing values is minimized. Java allows you to control access to classes, methods, and fields via so-called access specifiers. Java offers four access specifiers, listed below in decreasing accessibility: public protected default (no specifier) private We look at these access specifiers in more detail. public public classes, methods, and fields can be accessed from everywhere. The only constraint is that a file with Java source code can only contain one public class whose name must also match with the filename. If it exists, this public class represents the application or the applet, in which case the public keyword is necessary to enable your Web browser or appletviewer to show the applet. You use public classes, methods, or fields only if you explicitly want to offer access to these entities and if this access cannot do any harm. An example of a square determined by the position of its upper-left corner and its size: public class Square { // public class public x, y, size; // public instance variables } protected protected methods and fields can only be accessed within the same class to which the methods and fields belong, within its subclasses, and within classes of the same package, but not from anywhere else. You use the protected access level when it is appropriate for a class's subclasses to have access to the method or field, but not for unrelated classes. default (no specifier) If you do not set access to specific level, then such a class, method, or field will be accessible from inside the same package to which the class, method, or field belongs, but not from outside this package. This access-level is convenient if you are creating packages. For example, a geometry package that contains Square and Tiling classes, may be easier and cleaner to implement if the coordinates of the upper-left corner of a Square are directly available to the Tiling class but not outside the geometry package. private private methods and fields can only be accessed within the same class to which the methods and fields belong. private methods and fields are not visible within subclasses and are not inherited by subclasses. So, the private access specifier is opposite to the public access specifier. It is mostly used for encapsulation: data are hidden within the class and accessor methods are provided. An example, in which the position of the upper-left corner of a square can be set or obtained by accessor methods, but individual coordinates are not accessible to the user. public class Square { // public class private double x, y // private (encapsulated) instance variables public setCorner(int x, int y) { // setting values of private fields this.x = x; this.y = y; } public getCorner() { // setting values of private fields return Point(x, y); } } Summary of Access Specifiers The following table summarizes the access level permitted by each specifier. Situation public protected default private Accessible to class from same package? yes yes yes no Accessible to class from different package? yes no, unless it is a subclass no no Note the difference between the default access which is in fact more restricted than the protected access. Without access specifier (the default choice), methods and variables are accessible only within the class that defines them and within classes that are part of the same package. They are not visible to subclasses unless these are in the same package. protected methods and variables are visible to subclasses regardless of which package they are in. Access Modifiers In Java Access modifiers specifies who can access them. There are four access modifiers used in java. They are public, private, protected, no modifer (declaring without an access modifer). Using ‘no modifier’ is also sometimes referred as ‘package-private’ or ‘default’ or ‘friendly’ access. Usage of these access modifiers is restricted to two levels. The two levels are class level access modifiers and member level access modifiers. I) Class level access modifiers (java classes only) Only two access modifiers is allowed, public and no modifier If a class is ‘public’, then it CAN be accessed from ANYWHERE. If a class has ‘no modifer’, then it CAN ONLY be accessed from ‘same package’. II) Member level access modifiers (java variables and java methods) All the four public, private, protected and no modifer is allowed. public and no modifier – the same way as used in class level. private – members CAN ONLY access. protected – CAN be accessed from ‘same package’ and a subclass existing in any package can access. For better understanding, member level access is formulated as a table: Access Modifiers Same Class Same Package Subclass Other packages public Y Y Y Y protected Y Y Y N no access modifier Y Y N N private Y N N N First row {public Y Y Y Y} should be interpreted as: Y – A member declared with ‘public’ access modifier CAN be accessed by the members of the ‘same class’. Y – A member declared with ‘public’ access modifier CAN be accessed by the members of the ‘same package’. Y – A member declared with ‘public’ access modifier CAN be accessed by the members of the ‘subclass’. Y – A member declared as ‘public’ CAN be accessed from ‘Other packages’. Second row {protected Y Y Y N} should be interpreted as: Y – A member declared with ‘protected’ access modifier CAN be accessed by the members of the ‘same class’. Y – A member declared with ‘protected’ access modifier CAN be accessed by the members of the ‘same package’. Y – A member declared with ‘protected’ access modifier CAN be accessed by the members of the ‘subclass’. N – A member declared with ‘protected’ access modifier CANNOT be accessed by the members of the ‘Other package’. similarly interpret the access modifiers table for the third (no access modifier) and fourth (private access modifier) records. Instance Methods An instance method in a subclass with the same signature (name, plus the number and the type of its parameters) and return type as an instance method in the superclass overrides the superclass's method. The ability of a subclass to override a method allows a class to inherit from a superclass whose behavior is "close enough" and then to modify behavior as needed. The overriding method has the same name, number and type of parameters, and return type as the method it overrides. An overriding method can also return a subtype of the type returned by the overridden method. This is called a covariant return type. When overriding a method, you might want to use the @Override annotation that instructs the compiler that you intend to override a method in the superclass. If, for some reason, the compiler detects that the method does not exist in one of the superclasses, it will generate an error. For more information on @Override, see Annotations. Class Methods If a subclass defines a class method with the same signature as a class method in the superclass, the method in the subclass hides the one in the superclass. The distinction between hiding and overriding has important implications. The version of the overridden method that gets invoked is the one in the subclass. The version of the hidden method that gets invoked depends on whether it is invoked from the superclass or the subclass. Let's look at an example that contains two classes. The first is Animal, which contains one instance method and one class method: public class Animal { public static void testClassMethod() { System.out.println("The class" + " method in Animal."); } public void testInstanceMethod() { System.out.println("The instance " + " method in Animal."); } } The second class, a subclass of Animal, is called Cat: public class Cat extends Animal { public static void testClassMethod() { System.out.println("The class method" + " in Cat."); } public void testInstanceMethod() { System.out.println("The instance method" + " in Cat."); } public static void main(String[] args) { Cat myCat = new Cat(); Animal myAnimal = myCat; Animal.testClassMethod(); myAnimal.testInstanceMethod(); } } The Cat class overrides the instance method in Animal and hides the class method in Animal. The main method in this class creates an instance of Cat and calls testClassMethod() on the class and testInstanceMethod() on the instance. The output from this program is as follows: The class method in Animal. The instance method in Cat. As promised, the version of the hidden method that gets invoked is the one in the superclass, and the version of the overridden method that gets invoked is the one in the subclass. Modifiers The access specifier for an overriding method can allow more, but not less, access than the overridden method. For example, a protected instance method in the superclass can be made public, but not private, in the subclass. You will get a compile-time error if you attempt to change an instance method in the superclass to a class method in the subclass, and vice versa. Summary The following table summarizes what happens when you define a method with the same signature as a method in a superclass. Defining a Method with the Same Signature as a Superclass's Method Superclass Instance Method Superclass Static Method Subclass Instance Method Overrides Generates a compile-time error Subclass Static Method Generates a compile-time error Hides Note: In a subclass, you can overload the methods inherited from the superclass. Such overloaded methods neither hide nor override the superclass methods—they are new methods, unique to the subclass.
• java.applet Provides the classes necessary to create an applet and the classes an applet uses to communicate with its applet context. • java.awt Contains all of the classes for creating user interfaces and for painting graphics and images. • java.awt.color Provides classes for color spaces. • java.awt.datatransfer Provides interfaces and classes for transferring data between and within applications. • java.awt.dnd Drag and Drop is a direct manipulation gesture found in many Graphical User Interface systems that provides a mechanism to transfer information between two entities logically associated with presentation elements in the GUI. • java.awt.event Provides interfaces and classes for dealing with different types of events fired by AWT components. • java.awt.font Provides classes and interface relating to fonts • . java.awt.geom Provides the Java 2D classes for defining and performing operations on objects related to two-dimensional geometry. • java.awt.im Provides classes and interfaces for the input method framework. • java.awt.im.spi Provides interfaces that enable the development of input methods that can be used with any Java runtime environment. • java.awt.image Provides classes for creating and modifying images. • java.awt.image.renderable Provides classes and interfaces for producing rendering-independent images. • java.awt.print Provides classes and interfaces for a general printing API. • java.beans Contains classes related to developing beans -- components based on the JavaBeansTM architecture. • java.beans.beancontext Provides classes and interfaces relating to bean context. • java.io Provides for system input and output through data streams, serialization and the file system. • java.lang Provides classes that are fundamental to the design of the Java programming language. • java.lang.ref Provides reference-object classes, which support a limited degree of interaction with the garbage collector. • java.lang.reflect Provides classes and interfaces for obtaining reflective information about classes and objects. • java.math Provides classes for performing arbitrary-precision integer arithmetic (BigInteger) and arbitrary-precision decimal arithmetic (BigDecimal). • java.net Provides the classes for implementing networking applications. • java.nio Defines buffers, which are containers for data, and provides an overview of the other NIO packages. • java.nio.channels Defines channels, which represent connections to entities that are capable of performing I/O operations, such as files and sockets; defines selectors, for multiplexed, non-blocking I/O operations. • java.nio.channels.spi Service-provider classes for the java.nio.channels package. • java.nio.charset Defines charsets, decoders, and encoders, for translating between bytes and Unicode characters. • java.nio.charset.spi Service-provider classes for the java.nio.charset package. • java.rmi Provides the RMI package. java.rmi.activation Provides support for RMI Object Activation. • java.rmi.dgc Provides classes and interface for RMI distributed garbage-collection (DGC). • java.rmi.registry Provides a class and two interfaces for the RMI registry. • java.rmi.server Provides classes and interfaces for supporting the server side of RMI. • java.security Provides the classes and interfaces for the security framework. • java.security.acl The classes and interfaces in this package have been superseded by classes in the java.security package. • java.security.cert Provides classes and interfaces for parsing and managing certificates, certificate revocation lists (CRLs), and certification paths. • java.security.interfaces Provides interfaces for generating RSA (Rivest, Shamir and Adleman AsymmetricCipher algorithm) keys as defined in the RSA Laboratory Technical Note PKCS#1, and DSA (Digital Signature Algorithm) keys as defined in NIST's FIPS-186. • java.security.spec Provides classes and interfaces for key specifications and algorithm parameter specifications. • java.sql Provides the API for accessing and processing data stored in a data source (usually a relational database) using the JavaTM programming language • . java.text Provides classes and interfaces for handling text, dates, numbers, and messages in a manner independent of natural languages. • java.util Contains the collections framework, legacy collection classes, event model, date and time facilities, internationalization, and miscellaneous utility classes (a string tokenizer, a random-number generator, and a bit array) • . java.util.jar Provides classes for reading and writing the JAR (Java ARchive) file format, which is based on the standard ZIP file format with an optional manifest file. • java.util.logging Provides the classes and interfaces of the JavaTM 2 platform's core logging facilities. • java.util.prefs This package allows applications to store and retrieve user and system preference and configuration data. • java.util.regex Classes for matching character sequences against patterns specified by regular expressions. • java.util.zip Provides classes for reading and writing the standard ZIP and GZIP file formats. • javax.accessibility Defines a contract between user-interface components and an assistive technology that provides access to those components. • javax.crypto Provides the classes and interfaces for cryptographic operations. • javax.crypto.interfaces Provides interfaces for Diffie-Hellman keys as defined in RSA Laboratories' PKCS #3. • javax.crypto.spec Provides classes and interfaces for key specifications and algorithm parameter specifications. • javax.imageio The main package of the Java Image I/O API. • javax.imageio.event A package of the Java Image I/O API dealing with synchronous notification of events during the reading and writing of images. • javax.imageio.metadata A package of the Java Image I/O API dealing with reading and writing metadata. • javax.imageio.plugins.jpeg Classes supporting the built-in JPEG plug-in. • javax.imageio.spi A package of the Java Image I/O API containing the plug-in interfaces for readers, writers, transcoders, and streams, and a runtime registry. • javax.imageio.stream A package of the Java Image I/O API dealing with low-level I/O from files and streams. • javax.naming Provides the classes and interfaces for accessing naming services. • javax.naming.directory Extends the javax.naming package to provide functionality for accessing directory services. • javax.naming.event Provides support for event notification when accessing naming and directory services. • javax.naming.ldap Provides support for LDAPv3 extended operations and controls. • javax.naming.spi Provides the means for dynamically plugging in support for accessing naming and directory services through the javax.naming and related packages. • javax.net Provides classes for networking applications. • javax.net.ssl Provides classes for the secure socket package. • javax.print Provides the principal classes and interfaces for the JavaTM Print Service API. javax.print.attribute Provides classes and interfaces that describe the types of JavaTM Print Service attributes and how they can be collected into attribute sets. • javax.print.attribute.standard Package javax.print.attribute.standard contains classes for specific printing attributes. • javax.print.event Package javax.print.event contains event classes and listener interfaces. • javax.rmi Contains user APIs for RMI-IIOP. • javax.rmi.CORBA Contains portability APIs for RMI-IIOP. • javax.security.auth This package provides a framework for authentication and authorization. • javax.security.auth.callback This package provides the classes necessary for services to interact with applications in order to retrieve information (authentication data including usernames or passwords, for example) or to display information (error and warning messages, for example). javax.security.auth.kerberos This package contains utility classes related to the Kerberos network authentication protocol. • javax.security.auth.login This package provides a pluggable authentication framework. • javax.security.auth.spi This package provides the interface to be used for implementing pluggable authentication modules. • javax.security.auth.x500 This package contains the classes that should be used to store X500 Principal and X500 Private Crendentials in a Subject. • javax.security.cert Provides classes for public key certificates. • javax.sound.midi Provides interfaces and classes for I/O, sequencing, and synthesis of MIDI (Musical Instrument Digital Interface) data. • javax.sound.midi.spi Supplies interfaces for service providers to implement when offering new MIDI devices, MIDI file readers and writers, or sound bank readers. • javax.sound.sampled Provides interfaces and classes for capture, processing, and playback of sampled audio data. • javax.sound.sampled.spi Supplies abstract classes for service providers to subclass when offering new audio devices, sound file readers and writers, or audio format converters. • javax.sql Provides the API for server side data source access and processing from the JavaTM programming language. • javax.swing Provides a set of "lightweight" (all-Java language) components that, to the maximum degree possible, work the same on all platforms. • javax.swing.border Provides classes and interface for drawing specialized borders around a Swing component. • javax.swing.colorchooser Contains classes and interfaces used by the JColorChooser component. • javax.swing.event • Provides for events fired by Swing components. • javax.swing.filechooser Contains classes and interfaces used by the JFileChooser component. • javax.swing.plaf Provides one interface and many abstract classes that Swing uses to provide its pluggable look-and-feel capabilities. • javax.swing.plaf.basic Provides user interface objects built according to the Basic look and feel. • javax.swing.plaf.metal Provides user interface objects built according to the Java look and feel (once codenamed Metal), which is the default look and feel. • javax.swing.plaf.multi Provides user interface objects that combine two or more look and feels. • javax.swing.table Provides classes and interfaces for dealing with javax.swing.JTable. • javax.swing.text Provides classes and interfaces that deal with editable and noneditable text components • . javax.swing.text.html Provides the class HTMLEditorKit and supporting classes for creating HTML text editors. • javax.swing.text.html.parser Provides the default HTML parser, along with support classes. • javax.swing.text.rtf Provides a class (RTFEditorKit) for creating Rich-Text-Format text editors. • javax.swing.tree Provides classes and interfaces for dealing with javax.swing.JTree. • javax.swing.undo • Allows developers to provide support for undo/redo in applications such as text editors. • javax.transaction Contains three exceptions thrown by the ORB machinery during unmarshalling. • javax.transaction.xa Provides the API that defines the contract between the transaction manager and the resource manager, which allows the transaction manager to enlist and delist resource objects (supplied by the resource manager driver) in JTA transactions. • javax.xml.parsers Provides classes allowing the processing of XML documents. • javax.xml.transform This package defines the generic APIs for processing transformation instructions, and performing a transformation from source to result. • javax.xml.transform.dom This package implements DOM-specific transformation APIs. • javax.xml.transform.sax This package implements SAX2-specific transformation APIs. • javax.xml.transform.stream This package implements stream- and URI- specific transformation APIs. • org.ietf.jgss This package presents a framework that allows application developers to make use of security services like authentication, data integrity and data confidentiality from a variety of underlying security mechanisms like Kerberos, using a unified API. • org.omg.CORBA Provides the mapping of the OMG CORBA APIs to the JavaTM programming language, including the class ORB, which is implemented so that a programmer can use it as a fully-functional Object Request Broker (ORB). • org.omg.CORBA_2_3 The CORBA_2_3 package defines additions to existing CORBA interfaces in the Java 2 Standard Edition. These changes occurred in recent revisions to the CORBA API defined by the OMG. The new methods were added to interfaces derived from the corresponding interfaces in the CORBA package. This provides backward compatibility and avoids breaking the JCK tests. • org.omg.CORBA_2_3.portable Provides methods for the input and output of value types, and contains other updates to the org/omg/CORBA/portable package. • org.omg.CORBA.DynAnyPackage Provides the exceptions used with the DynAny interface (InvalidValue, Invalid, InvalidSeq, and TypeMismatch). • org.omg.CORBA.ORBPackage Provides the exception InvalidName, which is thrown by the method ORB.resolve_initial_references and the exception InconsistentTypeCode, which is thrown by the Dynamic Any creation methods in the ORB class. • org.omg.CORBA.portable Provides a portability layer, that is, a set of ORB APIs that makes it possible for code generated by one vendor to run on another vendor's ORB. • org.omg.CORBA.TypeCodePackage Provides the user-defined exceptions BadKind and Bounds, which are thrown by methods in in the class TypeCode. • org.omg.CosNaming Provides a naming service for Java IDL. • org.omg.CosNaming.NamingContextExtPackage This package contains the following classes, which are used in org.omg.CosNaming.NamingContextExt: • org.omg.CosNaming.NamingContextPackage This package contains Exception classes for the org.omg.CosNaming package. • org.omg.Dynamic This package contains the Dynamic module specified in the OMG Portable Interceptor specification, http://cgi.omg.org/cgi-bin/doc?ptc/2000-08-06, section 21.9. • org.omg.DynamicAny Provides classes and interfaces that enable traversal of the data value associated with an any at runtime, and extraction of the primitive constituents of the data value. • org.omg.DynamicAny.DynAnyFactoryPackage This package contains classes and exceptions from the DynAnyFactory interface of the DynamicAny module specified in the OMG The Common Object Request Broker: Architecture and Specification, http://cgi.omg.org/cgi-bin/doc?formal/99-10-07, section 9.2.2. • org.omg.DynamicAny.DynAnyPackage This package contains classes and exceptions from the DynAny interface of the DynamicAny module specified in the OMG The Common Object Request Broker: Architecture and Specification, http://cgi.omg.org/cgi-bin/doc?formal/99-10-07, section 9.2. • org.omg.IOP This package contains the IOP module specified in the OMG document The Common Object Request Broker: Architecture and Specification, http://cgi.omg.org/cgi-bin/doc?formal/99-10-07, section 13.6. • org.omg.IOP.CodecFactoryPackage This package contains the exceptions specified in the IOP::CodeFactory interface (as part of the Portable Interceptors spec). • org.omg.IOP.CodecPackage This package is generated from the IOP::Codec IDL interface definition. • org.omg.Messaging This package contains the Messaging module specified in the OMG CORBA Messaging specification, http://cgi.omg.org/cgi-bin/doc?formal/99-10-07. • org.omg.PortableInterceptor Provides a mechanism to register ORB hooks through which ORB services can intercept the normal flow of execution of the ORB. • org.omg.PortableInterceptor.ORBInitInfoPackage This package contains the exceptions and typedefs from the ORBInitInfo local interface of the PortableInterceptor module specified in the OMG Portable Interceptor specification, http://cgi.omg.org/cgi-bin/doc?ptc/2000-08-06, section 21.7.2. • org.omg.PortableServer Provides classes and interfaces for making the server side of your applications portable across multivendor ORBs. • org.omg.PortableServer.CurrentPackage Provides method implementations with access to the identity of the object on which the method was invoked. • org.omg.PortableServer.POAManagerPackage Encapsulates the processing state of the POAs it is associated with. • org.omg.PortableServer.POAPackage Allows programmers to construct object implementations that are portable between different ORB products. • org.omg.PortableServer.portable Provides classes and interfaces for making the server side of your applications portable across multivendor ORBs. • org.omg.PortableServer.ServantLocatorPackage Provides classes and interfaces for locating the servant. • org.omg.SendingContext Provides support for the marshalling of value types. • org.omg.stub.java.rmi Contains RMI-IIOP Stubs for the Remote types that occur in the java.rmi package. • org.w3c.dom Provides the interfaces for the Document Object Model (DOM) which is a component API of the Java API for XML Processing. • org.xml.sax Provides the classes and interfaces for the Simple API for XML (SAX) which is a component of the Java API for XML Processing. • org.xml.sax.ext Provides extension classes and interfaces for the Simple API for XML (SAX) which is a component of the Java API for XML Processing. • org.xml.sax.helpers Provides helper classes for the Simple API for XML (SAX) which is a component of the Java API for XML Processing. Java Platform, Standard Edition (Java SE) Name Acronym Description and Version History Available from Java Advanced Imaging JAI A set of interfaces that support a high-level programming model allowing to manipulate images easily. Java Data Objects JDO A specification of Java object persistence. JavaHelp A full-featured, extensible help system that enables you to incorporate online help in applets, components, applications, operating systems, and devices. Java Media Framework JMF An API that enables audio, video and other time-based media to be added to Java applications and applets. Java Naming and Directory Interface JNDI An API for directory services. Java Speech API JSAPI This API allows for speech synthesis and speech recognition. Java 3D J3D A scene graph-based 3D API. available here Java OpenGL JOGL A wrapper library for OpenGL. available here Java Mail (none) A framework to build mail and messaging applications available here Java USB for Windows (none) A USB communication of Java applications available here Java Platform, Enterprise Edition (Java EE) Bundled APIs (part of standard download) Name Acronym Java package(s) that contain the API Java Message Service JMS JavaServer Faces JSF javax.faces Optional APIs (downloaded separately) Name Acronym Available from Java API for XML-Based RPC JAX-RPC available here XQuery API for Java XQJ here and here Java Platform, Micro Edition (Java ME) Name Acronym Available from Connected Limited Device Configuration CLDC Reference implementation is available here Java Telephony API available here Unofficial APIs (Released by third parties) This list is very incomplete, as the number of APIs available for the Java platform is overwhelming. Rich Client Platforms Eclipse Rich Client Platform (RCP) NetBeans Platform Office_compliant libraries Apache POI Compression LZMA SDK, the Java implementation of the SDK used by the popular 7-Zip file archive software (available here) Game engines jMonkey Engine LWJGL Real-time libraries Javolution Windowing libraries Standard Widget Toolkit (SWT) Physics Libraries JBox2D JBullet
Java provides a rich set of pre-written classes, giving programmers an existing library of code to support files, networking, graphics, and general language routines; each major category being supported by a collection of classes known as a package. I'll be covering each of these packages in a later part of the tutorial series, but for now, will introduce you to one of the most important packages of all - java.lang. By default, each Java application/applet has access to the java.lang package. Inside java.lang are classes that represent primitive data types (such as int & char), as well as more complex classes. It contains classes pertaining to strings, string buffers, threads, and even the System class from which we obtain out input and output streams. Java.lang is quite extensive, and some aspects (such as threads) can be confusing for those new to the Java language. For this reason, I'll only present the more useful, less complex, parts of this package. This should allow you to experiment with some of the handy features of the Java language, while minimising the barrier to understanding. For more advanced Java programmers, you may wish to consult the Java API yourself, and experiment with other parts of java.lang not covered herein. Basic data types We've used some of the simple data types, such as strings and floating point numbers (double), but haven't actually looked at some of their methods. Below, I'll cover some of the more important data types : Object Integer Long Float Double Character String StringBuffer Class Object In Java, all classes are actually subclasses of class Object. In a previous tutorial, we covered what it meant to extend a class, and the syntax for creating new classes. When we define a class, class MyClass { ..... } we are actually implicitly extending MyClass from class Object. Thus, we can replace the above sample with the following : class MyClass extends Object { ..... } At first glance, this might not appear to be very important, except for academic interest. However, it actually has a profound impact - every class in Java shares the same properties, and hence methods of class Object. While there are several methods that might be of use, the most important of these is the toString() method. Every object can be explicitly converted into a string representation, by calling the toString() method which returns a string. Thus, we can explicitly convert objects, such as floating point numbers, integers, etc. If you construct a class yourself, you should consider overriding the toString method, to provide a suitable return value. double my_double = 3.14; String my_str = my_double.toString() Back to data types Numerical data types The numerical data types all share some common methods, which their inherit from class Number. All numbers are convertible to the basic numerical classes (int, long, float, double) using the following method calls : int intValue(); long longValue(); float floatValue(); double doubleValue(); Back to data types Class Integer / Long Integer, and the longer form, long, represent whole number values. Integers and longs can be interchanged through the longValue() and intValue() methods, and can also be converted to floats and doubles using the floatValue() and doubleValue(). Integer my_integer = new Integer(256); Long my_long = my_integer.longValue(); Back to data types Class Float / Double Floating point values, and the longer form, double, represent decimal (fractional) values. Floats and doubles can be interchanged through the doubleValue() and floatValue() methods, and can also be converted to integers and longs using the longValue() and intValue() methods. Its important to remember, however, that there will be a loss of precision, as integers and longs cannot retain the fractional component. Float my_float = new Float(3.14); Double my_double = new Double (my_float.doubleValue()); // Print out double (3.14) System.out.println( "Double : " + my_double); // Print out integer (3) System.out.println( "Integer: " + my_double.intValue() ); Back to data types Class Character The character class contains a large set of character comparison routines, in the form of static methods. We haven't really discussed static methods before - a static method is a method that is common to all objects of the type that class. In fact, you don't even need to instantiate an object from a class containing a static method to call it! if (Character.isLowerCase( 'H' )) { System.out.println ("Lowercase value detected"); } else { System.out.println ("Uppercase value detected"); } The character class offers a wide range of character comparison routines; the most useful are listed below : static boolean isDigit( char c ); static boolean isLetter( char c ); static boolean isLetterOrDigit( char c ); static boolean isLowerCase( char c ); static boolean isUpperCase( char c ); static char toUpperCase( char c ); static char toLowerCase( char c ); Back to data types Class String Programmers who are familiar with C will understand a string as being an array of characters. Though Java has aspects of C/C++, the definition for a string differs strongly. Under Java, a string is a unique object, which has its own set of methods. Gone are the days of importing a string library, we simply invoke methods of a string object. Some of the more useful routines are listed below : // Returns the character at offset index public char charAt(int index); // Compares string with another, returning 0 if there's a match public int compareTo(String anotherString); // Returns a new string equal to anotherString // appended to the current string public String concat(String anotherString); // Returns the length of the current string public int length(); // Returns true if the current string begins with prefix public boolean startsWith(String prefix); // Returns true if the current string ends in suffix public boolean endsWith(String suffix); // Returns the remainder of the string, starting from offset beginIndex public String substring(int beginIndex); // Returns a substring from offset beginIndex to offset endIndex public String substring(int beginIndex, int endIndex); // Returns the current string, converted to lowercase public String toLowerCase(); // Returns the current string, converted to uppercase public String toUpperCase(); Back to data types Class StringBuffer While strings are extremely useful, there are some tasks that require a more flexible sequence of characters. In cases where strings are being constantly modified, and appended to, it is not always efficient to simply recreate a string every time you wish to concatenate it with another. The StringBuffer class has an append method, which extends the capacity of the StringBuffer when required to accommodate varying lengths. The append method even allows you to add chars, booleans, integers, longs, floats & doubles. Some of the more useful StringBuffer methods are given below : // Appends the string version of a boolean to the buffer public StringBuffer append(boolean b); // Appends a character to the buffer public StringBuffer append(char c); // Appends the string version of a integer to the buffer public StringBuffer append(int i); // Appends the string version of a long to the buffer public StringBuffer append(long l); // Appends the string version of a float to the buffer public StringBuffer append(float f); // Appends the string version of a double to the buffer public StringBuffer append(double d); // Appends the string version (toString method) of an object to the buffer public StringBuffer append(Object obj); // Appends the string to the buffer public StringBuffer append(String str); // Returns the character at offset index public char charAt(int index); // Returns the current length of the string buffer public int length(); // Reverses the order of characters in the string buffer public StringBuffer reverse(); // Truncates, or pads with null characters, the buffer to a certain length public void setLength(int newLength); // Returns a string, representing the string buffer public String toString(); Back to data types Class System The System class is perhaps one of the most important classes contained within the java.lang package, as this class provides us with the input and output streams. Without these, it would be very difficult to interact with the user! public static InputStream in; public static PrintStream out; public static PrintStream err; There is one input stream, and two output streams (out/err). Normal messages should be passed to out, but exceptional cases and error conditions should be written to err (standard error on Unix systems). Since these attributes are static, we need not even instantiate the System class to access them. To print, for example, we can simply use the statement System.out.println() The System class also has some interesting methods which are of use to Java programmers. public static void exit(int status) public static String getProperty(String key); System.exit Exit allows a Java programmer to immediately terminate execution of the program, and to return a status code. By convention, a non-zero status code indicates an error has occurred, and on PC systems, should set the appropriate DOS errorlevel. If your Java application has been run from a batch file, you can actually test to see if it has executed correctly. Presented below is a test class, and a batch file that when executed will check for a status code of six. class test { public static void main(String args[]) { System.exit (6); } } Listing 1.0 - Test.java @echo off if ERRORLEVEL 6 echo Errorlevel 1 detected REM Execute test.class java test if ERRORLEVEL 6 echo An error has occurred. Please restart Listing 1.1 - Test.bat A check is made, in two places, to see if errorlevel six has been set, so that the change in errorlevel can be seen. Its also important to note that an errorlevel will last longer than the duration of the batch file - running test.bat a second time will mean that the first error check returns true. Back to System class System.getProperty Another useful method from the System class is getProperty. Via the getProperty method, a Java application can gain information about the operating system under which it is running, the vendor and version of the Java virtual machine, and even the user name and home directory path of the current user under Unix based systems. Some of the more common system properties are listed in the table below. Key Description of associated value java.version Java version number java.vendor Java-vendor-specific string java.vendor.url Java vendor URL java.home Java installation directory java.class.version Java class format version number java.class.path Java classpath os.name Operating system name os.arch Operating system architecture os.version Operating system version file.separator File separator ("/" on Unix) path.separator Path separator (":" on Unix) line.separator Line separator ("\n" on Unix) user.name User account name user.home User home directory user.dir User's current working directory Table 1.0 - getProperty key/value pairs Accessing the system properties is as simple as calling the static getProperty method and passing a key from the table as a parameter. An example is shown below, which displays the operating system of the computer it is running on. class GetPropertyDemo { public static void main(String args[]) { // Display value for key os.name System.out.println ( System.getProperty("os.name") ); } }
Classes should implement the Comparable interface to control their natural ordering. Objects that implement Comparable can be sorted by Collections.sort() and Arrays.sort() and can be used as keys in a sorted map or elements in a sorted set without the need to specify a Comparator. « Interface » Comparable + compareTo(Object) : int compareTo() compares this object with another object and returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the other object. Use Comparator to sort objects in an order other than their natural ordering. « Interface » Comparator + compare(Object, Object) : int + equals(Object) : boolean compare() compares its two arguments for order, and returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second. import java.util.*; public class TestCollections { public static void main(String[] args) { List list = new LinkedList(); list.add(new Book("Patterns", 12345)); list.add(new Book("Patterns", 34567)); list.add(new Book("Examples", 23456)); Collections.sort(list); Collections.sort(list, new Comparator() { public int compare(Object obj1, Object obj2) { Book book1 = (Book) obj1; Book book2 = (Book) obj2; return book1.isbn - book2.isbn; } }); } } public class Book implements Comparable { String title; int isbn; Book(String title, int isbn) { this.title = title; this.isbn = isbn; } public int compareTo(Object object) { Book other = (Book) object; if (this.title.equals(other.title)) { return this.isbn - other.isbn; } return this.title.compareTo(other.title); } }
The StringBuffer and StringBuilder classes are used when there is a necessity to make alot of modifications to Strings of characters. Unlike Strings objects of type StringBuffer and Stringbuilder can be modified over and over again with out leaving behind alot of new unused objects. The StringBuilder class was introduced as of Java 5 and the main difference between the StringBuffer and StringBuilder is that StringBuilders methods are not thread safe(not Synchronised). It is recommended to use StringBuilder whenever possible because it is faster than StringBuffer. However if thread safety is necessary the best option is StringBuffer objects. Example: public class Test{ public static void main(String args[]){ StringBuffer sBuffer = new StringBuffer(" test"); sBuffer.append(" String Buffer"); System.ou.println(sBuffer); } } This would produce following result: test String Buffer StringBuffer Methods: Here is the list of important methods supported by StringBuffer class: SN Methods with Description 1)public StringBuffer append(String s) Updates the value of the object that invoked the method. The method takes boolean, char, int, long, Strings etc. 2)public StringBuffer reverse() The method reverses the value of the StringBuffer object that invoked the method. 3)public delete(int start, int end) Deletes the string starting from start index until end index. 4)public insert(int offset, int i) This method inserts an string s at the position mentioned by offset. 5 replace(int start, int end, String str) This method replaces the characters in a substring of this StringBuffer with characters in the specified String. Here is the list of other methods (Except set methods ) which are very similar to String class: SN Methods with Description 1 int capacity() Returns the current capacity of the String buffer. 2 char charAt(int index) The specified character of the sequence currently represented by the string buffer, as indicated by the index argument, is returned. 3 void ensureCapacity(int minimumCapacity) Ensures that the capacity of the buffer is at least equal to the specified minimum. 4 void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) Characters are copied from this string buffer into the destination character array dst. 5 int indexOf(String str) Returns the index within this string of the first occurrence of the specified substring. 6 int indexOf(String str, int fromIndex) Returns the index within this string of the first occurrence of the specified substring, starting at the specified index. 7 int lastIndexOf(String str) Returns the index within this string of the rightmost occurrence of the specified substring. 8 int lastIndexOf(String str, int fromIndex) Returns the index within this string of the last occurrence of the specified substring. 9 int length() Returns the length (character count) of this string buffer. 10 void setCharAt(int index, char ch) The character at the specified index of this string buffer is set to ch. 11 void setLength(int newLength) Sets the length of this String buffer. 12 CharSequence subSequence(int start, int end) Returns a new character sequence that is a subsequence of this sequence. 13 String substring(int start) Returns a new String that contains a subsequence of characters currently contained in this StringBuffer.The substring begins at the specified index and extends to the end of the StringBuffer. 14 String substring(int start, int end) Returns a new String that contains a subsequence of characters currently contained in this StringBuffer. 15 String toString() Converts to a string representing the data in this string buffer.
Pass by value in java means passing a copy of the value to be passed. Pass by reference in java means the passing the address itself. In Java the arguments are always passed by value. Java only supports pass by value. With Java objects, the object reference itself is passed by value and so both the original reference and parameter copy both refer to the same Java object. Java primitives too are passed by value.
Each of Java's eight primitive data types has a class dedicated to it. These are known as wrapper classes, because they "wrap" the primitive data type into an object of that class. So, there is an Integer class that holds an int variable, there is a Double class that holds a double variable, and so on. The wrapper classes are part of the java.lang package, which is imported by default into all Java programs. The following discussion focuses on the Integer wrapper class, but applies in a general sense to all eight wrapper classes. Consult the Java API documentation for more details. The following two statements illustrate the difference between a primitive data type and an object of a wrapper class: int x = 25; Integer y = new Integer(33); The first statement declares an int variable named x and initializes it with the value 25. The second statement instantiates an Integer object. The object is initialized with the value 33 and a reference to the object is assigned to the object variable y. The memory assignments from these two statements are visualized public class FindRanges { public static void main(String[] args) { System.out.println("Integer range:"); System.out.println(" min: " + Integer.MIN_VALUE); System.out.println(" max: " + Integer.MAX_VALUE); System.out.println("Double range:"); System.out.println(" min: " + Double.MIN_VALUE); System.out.println(" max: " + Double.MAX_VALUE); System.out.println("Long range:"); System.out.println(" min: " + Long.MIN_VALUE); System.out.println(" max: " + Long.MAX_VALUE); System.out.println("Short range:"); System.out.println(" min: " + Short.MIN_VALUE); System.out.println(" max: " + Short.MAX_VALUE); System.out.println("Byte range:"); System.out.println(" min: " + Byte.MIN_VALUE); System.out.println(" max: " + Byte.MAX_VALUE); System.out.println("Float range:"); System.out.println(" min: " + Float.MIN_VALUE); System.out.println(" max: " + Float.MAX_VALUE); } } Method Purpose Constructors Integer(i) constructs an Integer object equivalent to the integer i Integer(s) constructs an Integer object equivalent to the string s Class Methods parseInt(s) returns a signed decimal integer value equivalent to string s toString(i) returns a new String object representing the integer i Instance Methods byteValue() returns the value of this Integer as a byte doubleValue() returns the value of this Integer as an double floatValue() returns the value of this Integer as a float intValue() returns the value of this Integer as an int longValue() returns the value of this Integer as a long shortValue() returns the value of this Integer as a short toString() returns a String object representing the value of this Integer
Math class is declared final, so you cannot extend it. Constructor of Math class is private, so you cannot create an instance. Methods and constants from Math class are static, public class MainClass{ public static void main(String args[]) { System.out.println(Math.E); System.out.println(Math.PI); System.out.println(Math.abs(-1234)); System.out.println(Math.cos(Math.PI/4)); System.out.println(Math.sin(Math.PI/2)); System.out.println(Math.tan(Math.PI/4)); System.out.println(Math.log(1)); System.out.println(Math.exp(Math.PI)); for(int i=0;i<3;++i) System.out.print(Math.random()+" "); System.out.println(); } }
No comments:
Post a Comment