Download Java Lecture 2 The Language

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Java
Lecture 2
The Language
Variables:
Java is a strongly typed language, which means that every variable and every
expression has a type that is known at compile time. There are two general types
of variables in Java - primitive types and reference types.
Primitive types are the regular types we've been using in C++ plus some others.
They are:
byte
short
int
long
float
double
char
boolean
8-bit integer
16-bit integer
32-bit integer
64-bit integer
32-bit floating point
64-bit floating point
16-bit unicode character
true or false
Reference types are references to other variables (like pointers!) The reference
types are class types, interface types, and array types. There is also a special null
type. An object in Java is a dynamically created instance of a class type or a
dynamically created array. The values of a reference type are references to
objects.
Arrays:
int FrogAges [];
int[] BugAges;
// declares FrogAges to be an array reference
// declares BugAges to be an array reference
// Then to create
FrogAges = new int [6];
// You can do both as:
int AntAges [] = {2,5,6,2};
double 2dArray [] [] = new double[2][100];
Class objects:
Point origin = new Point(0,0);
// A String can be implicitly created by a + operator:
int x, y;
String s = "(" + x + "," + y + ")";
// The String class is in the java.lang package.
Point High;
// this contains a reference to a null object
Interface types:
An interface is like an abstract class - we'll talk about them later.
There may be many references to the same object.
class Value { int val; }
class Test {
public static void main(String[] args) {
int i1 = 3;
int i2 = i1;
i2 = 4;
System.out.print("i1==" + i1);
// no linefeed
System.out.println(" but i2==" + i2);
Value v1 = new Value();
v1.val = 5;
Value v2 = v1;
v2.val = 6;
System.out.print("v1.val==" + v1.val);
System.out.println(" and v2.val==" + v2.val);
}
}
This produces output:
i1==3 but i2==4
v1.val==6 and v2.val==6
Passing argunments:
Intrinsics are ALWAYS passed by value and reference variable as
references.
If you want to pass an intrinsic by reference you have to use a wrapper
class.
Wrapper classes such as Integer, Byte, Boolean, etc. act just like
the intrinsics but are class objects.
Scope:
Most, but not all, C++ scope concepts continue. A notable exception is
the following:
for(int i=0;i<10;i++) {
}
// i undefined – out of scope
Operators:
There are no surprises here, compared to C++. There are two other operators,
though:
>>>
unsigned right shift (>> is a signed shift).
instanceof
At run time, the result of the instanceof operator is
true if the value of the RelationalExpression is not
null and the reference could be cast to the
ReferenceType without raising a
ClassCastException. Otherwise the result is false.
class Point { int x, y; }
class Element { int atomicNumber; }
class Test {
public static void main(String[] args) {
Point p = new Point();
Element e = new Element();
if (e instanceof Point) { // compile-time error
System.out.println("I get your point!");
p = (Point)e; // compile-time error
}
}
}
This example results in two compile-time errors. The cast (Point)e
is incorrect because no instance of Element or any of its possible
subclasses (none are shown here) could possibly be an instance of
any subclass of Point. The instanceof expression is incorrect for
exactly the same reason. If, on the other hand, the class Point were
a subclass of Element (an admittedly strange notion in this
example):
class Point extends Element { int x, y; }
then the cast would be possible, though it would require a run-time
check, and the instanceof expression would then be sensible and
valid. The cast (Point)e would never raise an exception because it
would not be executed if the value of e could not correctly be cast
to type Point.
Control Structures:
while
same as C++
do-while
same as C++
if-else
same as C++
switch
same as C++
for
same as C++ except the scope of the control variable
continue
same as C++
goto
not allowed
labeled break:
tolabel:
while ()
{
… break tolabel;
}
try-catch-finally
the try-catch part is the same (except no …). Finally is
new. The finally block is executed before control exits a
method, no matter what, even if the try bloc includes a
return or throws an exception.
throw
same as C++
main Method of Applications
The java runtime system executes a Java program by calling the application's
main method. But everything is a class and this is in the public class of the
application.
class Test {
public static void main(String[] args) {
}
}
In C++/C, we get int argc, char *argv[]. In Java we get String[]. But args.length
contains the number of array elements. So, C++
void main(int argc, char *argv[] ) {
for(int i=0;i<argc;i++)
printf("%s\n", argv[i]);
}
is, in Java,
class SomeThing {
public static void main(String[] args) {
for(int i=0;i<args.length;i++)
System.out.println( args[i] );
}
}
Java applets don't have a main method.
Command-Line Arguments:
Java programs can accept three types of command line arguments:
options
like -verbose
flags
like -f (single character)
arguments
follows an option
// Here's a class to parse a command line:
class ParseCmdLine {
public static void main(String[] args) {
int i = 0, j;
String arg;
char flag;
boolean vflag = false;
String outputfile = "";
while (i < args.length && args[i].startsWith("-")) {
arg = args[i++];
// use this type of check for "wordy" arguments
if (arg.equals("-verbose")) {
System.out.println("verbose mode on");
vflag = true;
}
// use this type of check for arguments that require arguments
else if (arg.equals("-output")) {
if (i < args.length)
outputfile = args[i++];
else
System.err.println("-output requires a filename");
if (vflag)
System.out.println("output file = " + outputfile);
}
// use this type of check for a series of flag arguments
else {
for (j = 1; j < arg.length(); j++) {
flag = arg.charAt(j);
switch (flag) {
case 'x':
if (vflag) System.out.println("Option x");
break;
case 'n':
if (vflag) System.out.println("Option n");
break;
default:
System.err.println("ParseCmdLine: illegal option " + flag);
break;
}
}
}
}
if (i == args.length) System.err.println("Usage: ParseCmdLine [-verbose] [-xn] [output afile] filename");
else System.out.println("Success!");
}
}
Exceptions:
We've seen the catching and throwing side above. At the end of an argument list,
you can add a throws statement such as:
// IOException is a class in java io
public static void main(String[] args) throws java.io.IOException
// Exception is a class in java.lang that takes a string arg giving
// the reason
public ComplexNumber Divide(double d ) throws Exception
{
if ( d == 0.0 )
throw new Exception("Divide by zero");
// rest
}
Standard Input and Output Streams:
System is part of java.lang package. Among the facilities provided by the System
class are standard input, standard output, and error output streams, access to
externally defined "properties", a means of loading files and libraries, and a utility
method for quickly copying a portion of an array.
System.in
System.out
System.err
is like stdin
is like stdout
is like stderr
Standard in and out:
import java.io.*;
// within the class
try {
byte bArray[] = new byte[128];
System.in.read( bArray );
System.out.println( bArray );
wants a String
String s = new String(bArray,0);
System.out.println( s );
}
catch ( IOException ioe ) {
// handle an io error
}
// just reads bytes
// garbage - because bArray
// now ok
Low-level File streams:
FileInputStream in = new FileInputStream("junk.txt");
// add buffering
BufferedInputStream bin = new BufferedInputStream( in );
FileOutputStream out = new FileOutputStream( "CopyOfJunk.txt" );
BufferedOutputStream bout = new BufferedOutputStream( out );
// read
byte bArray[] = new byte[250];
while ( bin.available() > 0 ) {
int nRead = bin.read( bArray );
bout.write( bArray,0, nRead);
}
To convert to higher levels from bytes:
char c = (char)bArray[i];
int nInt = (int)bArray[i];
// Creates a string representation of the first argument in the radix
// specified by the second argument.
String s = Integer.toString( nInt , 16);
Better answer: DataInputStream and DataOutputStream.
Classes:
Class declarations and concepts similar, but member functions are defined within
the class. There is no idea of an inline routine.
abstract public class BankAccount
{
private static double m_dCurrentInterestRate;
private double
m_dBalance;
// constructor
BankAccount( double dInitial )
{
m_dBalance = dInitial;
}
// default constructor
BankAccount()
{
m_dBalance = 0;
}
// static function to initialize the rate
public static void Rate(double r )
{
m_dCurrentInterestRate = r;
}
// withdraw
public void Withdraw( double w )
{
if ( w >= 0 ) {
if ( m_dBalance - w > 0 )
m_dBalance-= w;
}
}
// deposit
public void Deposit( double d )
{
if ( d > 0 ) m_dBalance+= d;
}
}
// note no semicolon
Final:
If you use "final" in place of abstract or public, then the class cannot be
extended. It is the final one. Why??? Security: If you extend a class
then it behaves like the original plus some other behavior. Hackers use
this to get control. Design: The creator feels the classes are perfect as is!
Inheritance:
import BankAccount;
//
//
// CheckingAccount
//
//
public class CheckingAccount extends BankAccount
{
private int
private static int
m_nAccountNumber;
m_nNextAccountNumber = 10000;
// Constructor
CheckingAccount(double dInitial )
{
super( dInitial );
m_nAccountNumber = m_nNextAccountNumber++;
}
}
CheckingAccount is a subclass of BankAccount.
BankAccount is a superclass of CheckingAccount.
NOTE: If the constructor for the subclass is not specifically overriden it
automatically calls the default constructor of the super class before
starting.
Note on projects:
To create another class in your project, click on "insert" then "New Class"
to get:
A driver program:
import BankAccount;
//
//
// Test
//
//
public class Test
{
public static void main( String args[])
{
BankAccount ba = new BankAccount( 55.); // error
CheckingAccount ca = new CheckingAccount( 565.);
}
}
Interfaces:
An interface is like an abstract class. It provides the interface - it declares
a set of member functions and constants without any implementations. An
interface can be public or private. A class that implements an interface
doesn't inherit anything - it's just promising to provide what the interface
lists.
// create this just like a new public class
public interface Account
{
public abstract void Deposit(double d);
public abstract void Withdraw(double d);
}
import BankAccount;
//
//
// CheckingAccount
//
//
public class CheckingAccount extends BankAccount implements Account
{
// details
}
this and super:
this is similar to this in C++. Here's an example:
class Frog {
int eyeball;
void Poke( int eyeball )
{
this.eyeball = 7;
eyeball = 9;
// this is the class attribute
// the one coming in
}
}
If your class hides a superclass member, you can get it with
super.aSuperclassMethod();
Copy constructor:
Yes, we still need these. Here's a reason why.
String Gary = new String("Gary Koehler");
String John; // these are references
John = Gary; // John now points to "Gary Koehler"
String GaryK = String(Gary);
// GaryK is another object with the same value as Gary
destructor => finalize method:
Objects are automatically destructed when nobody references them
anymore. Routine finalize() is called at that point. Normally nothing
needs to be done since most of the time we're just cleaning up pointers. A
common use is for closing files.
Here is how it's done:
protected void finalize() throws Throwable
{
}
// Throwable is a class that contains Exception and Error
subclasses
Access:
Things are similar to C++. Here are the details:
<default> // accessible to all members of same package
this is called "friendly"
public // accessible to all methods of all packages
private // accessible only to other members of same classs
protected // accesible only to subclasses
Specifier
private
protected
public
package
class
√
√
√
√
subclass
package
world
√
√
√
√
√
√
Multiple Inheritance:
Java doesn't support multiple inheritance BUT a class can implement
several interfaces which provides most of what multiple inheritance gives
you.
Overloading:
Member functions can be overloaded. Operators cannot.
However, Java has some built-in overloaded operators. "+" means
concatenation for Strings.
Polymorphism:
Java is polymorphic, but only to a point. Since there are no pointer types,
we don't need the virtual business we saw in C++.
Declarations:
Constants (like const):
final double PI = 3.1415;
final double AVOGADRO = 6.023e23;
Transient variables:
This modifier tells Java that the member variable is not a persistent
part of the object and does not need to be archived.
transient int i;
Volatile variables:
When multiple threads can access a member variable, to keep
things in synch, declare the variable volatile which will cause the
variable to be loaded from memory before each use.
volatile int i;
Packages:
A package is a loose affiliation of classes and interfaces. Our Account package is
one example.
package Accounts;
// notice the public is off
interface Account
{
public abstract void Deposit(double d );
public abstract void Withdraw(double d );
}
abstract class BankAccount
{
private static double m_dCurrentInterestRate;
private double
m_dBalance;
// constructor
BankAccount( double dInitial )
{
m_dBalance = dInitial;
}
// default constructor
BankAccount()
{
m_dBalance = 0;
}
// static function to initialize the rate
public static void Rate(double r )
{
m_dCurrentInterestRate = r;
}
// withdraw
public void Withdraw( double w )
{
if ( w >= 0 ) {
if ( m_dBalance - w > 0 )
m_dBalance-= w;
}
}
// deposit
public void Deposit( double d )
{
if ( d > 0 ) m_dBalance+= d;
}
}
class CheckingAccount extends BankAccount implements Account
{
private int
private static int
m_nAccountNumber;
m_nNextAccountNumber = 10000;
// Constructor
CheckingAccount(double dInitial )
{
super( dInitial );
m_nAccountNumber = m_nNextAccountNumber++;
}
}
A Summary
C++
Intrinsic Types
Comments
strings
operators
Boolean operators
-- none --- none -char
short int
int
long
float
double
unsigned
//
/* … */
Null terminated char
arrays
-- none --- none --- none -||
&&
Labeled break
for loop
New types
for(int i=0;i<10;i++) {
}
i defined still
enum
typedef
struct
access
Java
Type
Size
Default value
boolean - 8 bits
false (not number)
byte
- 8 bits
0
char
- 16 bits
‘x0’
short
- 16 bits
0
int
- 32 bits
0
long
- 64 bits
0
float
- 32 bits
0.0F
double - 64 bits 0.0D
-- none -//
/* … */
/** immediately before declaration */
String class, not null terminated
character array
>>> unsigned right shift
instanceof
|
no short circuiting
&
no short circuiting
||
&&
tolabel:
while ()
{
… break tolabel;
}
for(int i=0;i<10;i++) {
}
i undefined – out of scope
-- none --- none --- none -<default> // accessible to all members
of same package
public:
public // accessible to all methods of
all packages
private:
private // accessible only to other
members of same classs
protected // accesible only to
subclasses
Member functions
Constant members
Can be defined separate
class declaration.
Can have inline functions
const
Source file name
Pointers
Anything.cpp
* and **
New objects
Deleting objects
Passing arguments
new ObjectType;
new ObjectType[6];
delete and delete []
By value unless & used
Templates
supported
Arrays
int *a;
int nArray[];
int nArray[] = {1,2,3};
null
this
Copy constructors
Initialization
within class
definition
Null or 0
pointer
-- none --- none -C++ uses these implicitly
in many places.
class::nValue = 3;
-- none --
destructors
~ClassName
Inheritance
class xx public yy {
multiple
abstract class
Package
Only defined within class.
No concept of inline.
final
// when used on a clas, means it can't
be extended
PublicClass.java
No pointers, only references
Eg.
String RefToStringType;
RefToStringType = new String();
No reference to functions allowed
new ObjectType;
new ObjectType[6];
Automatic once nothing references it.
Intrinsics by value
Class objects by reference
Not supported directly
Use interface
No pointers
int nArray[]; // nArray array reference
int[] nArray;
int nArray[] = {1,2,3}; // same as C++
Arrays are actually a class
null
reference
this( args) // constructor call from a
constructor
super( args ) or super.
Java never calls a copy constructor
automatically.
static int nValue = 3;
int nOtherInt = 8;
static String[] m_sNames = new
Strings[nValue]; // initialized in order
they occur
void finalizer() // normally don’t need
this – used by garbage collector when
it deems necessary
class xx extends yy {
no multiple
abstract public class xx {
abstract member(); // can then be
overridden
package name.name // must be first
line of source
unnamed is default package
import class // follows package
statement (if any)
import srd.math.* // gets all classes
CLASSPATH environment string
holds root for search for packages
java.lang // fundamental classes
Libraries
java.applet // classes needed for
applets
java.awt // abstract window classes
java.io // i/o package
java.net // low-level internet i/o
java.util // general utilities
Super class of all classes:
Object class
protected Object clone // returns copy
of object
public final Object getClass // returns
the class Object - a description
String toString // unicode description
of object.
Exceptions
try, catch. throw
try, catch, throw
Method (args) throws Exception
{
object must be subclass of Throwable
Standard I/O
cin
cout
cerr
finally // a block executed whether
try or catch used.
System.in
System.out
System.err