You are on page 1of 62

Data Types

Primitive Data Types


Type Representation

Range

byte

8-bit, signed

-128 to 127

short

16-bit, signed

-32768 to 32767

int

32-bit, signed

-2147483648 to 2147483647

long

64-bit, signed

float

32-bit

double 64-bit
char
boolean

-9223372036854775808 to
9223372036854775807
1.40239846e-45 to 3.40282347e+38
4.94065645841246544e-324 to
1.79769313486231570e+308

16-bit, unsigned, Unicode

Java Operators
Precedence

Operator

Description

++, --

Increment and decrement

+, -

Unary plus and minus

Bitwise complement

Boolean

*, /, %

Multiplication, division, remainder

+, -

Addition and subtraction

String

<<

Left shift

>>

Right shift with sign extension

>>>

Right shift with no extension

<, <=, >, >=

Numeric comparison

instanceof

Type comparison

==, !=

Equality and inequality of value

==, !=

Equality and inequality of reference

&

Bitwise AND

Bitwise XOR

Bitwise OR

10

&&

Conditional AND

11

||

Conditional OR

12

?:

Conditional ternary operator

13

= *=, /=, %=, +=, -=, <<=, >>=, >>>=, &=, ^=, |=
Assignment

Keywords
abstract

default

goto

null

synchronized

boolean

do

if

package

this

break

double

implements

private

throw

byte

else

import

protected

throws

case

extends

instanceof

public

transient

catch

false

int

return

true

char

final

interface

short

try

class

finally

long

static

void

const

float

native

super

volatile

continue

for

new

switch

while

Comments
Java supports three styles of comments:
A standard C-style comment, where all of the characters between
/* and */ are ignored.
A single-line comment, where all of the characters from
// to the end of the line are ignored.
A documentation comment that begins with
/** and ends with */.

Literals
Integer literals
Integer literals can be specified in octal (base 8), decimal (base 10), or
hexadecimal (base 16).
int i = 1230;
int i = 01230; // i = 664 decimal
int i = 0xFFFF;
Floating-point literals
Floating-point literals are of type double unless they are
suffixed with an f denoting that they are to be produced
as a float value:
double d = 8.31;
double e = 3.00e+8;

Character literals
A literal character value can be specified either as a single-quoted
character or as an escaped ASCII or Unicode sequence:
char a = 'a';
char newline = '\n';
char ch = 88 ; //code for X
Boolean Literals
It can have only one of two possible values, true or false
boolean b = false;

Type Conversion and Casting

When one type of data is assigned to another type of variable, an


automatic type conversion will take place if
The two types are compatible
The destination type is larger than the source type.

Casting Incompatible Types


To create a conversion between two incompatible types, you must
use a cast.
(target-type) value;

Casting
1) int a;
a = 10;
byte b;
b = (byte) a;

2) byte b;
int i = 257;
b = (byte) i; // 1
3) double d = 223.22;
int i = (int) d;

// 223

Automatic Type Promotion in Expressions

Java automatically promotes each byte type or short operand to int


when evaluating an expression.
byte b= 50;
b = b * 2; // Error. Cannot assign an int to a byte
b = (byte) (b*2); //

valid

Array Creation and Initialization


As in C, array indices start with zero.
After creation, the array elements are initialized to the default values for
their type.
For numeric types, this means the elements are initially zero:
int [] grades = new int [30];
grades[0] = 99;
grades[1] = 72;
Java supports the C-style curly braces {} construct for
creating an array and initializing its elements when it is
declared:
int [] primes = { 1, 2, 3, 5, 7, 7+4 };
An array object of the proper type and length is
implicitly created.

HelloWorld.java
public class HelloWorld
{

public static void main(String[] args)


{
System.out.println("Hello World!");
}

}
C:> javac HelloWorld.java
//produces the HelloWorld.class
C:> java HelloWorld
//when you invoke
the
interpreter, you do not supply the .class

class P
{
public static void main(String args[])
{

int x =34;
int y =42;
System.out.println("X = " + x);
System.out.println("y = " + y);
int z = x+y;
System.out.println("z = " + z);

}
}
All local variables has to be initialized before using.

Arithmetic Operators and Logical Operators


are same as that of C Programming Language.

The Left Shift operator


int i;
byte a = 256,b;
i = a<< 2;
b = (byte) (a<<2);

System.out.println( i and b : + i + + b);


// i and b : 256 and 0
a is promoted to int for the purpose of evaluation, left shifting the value
64 twice results in I containing the value 256
0100 0000
0000 0001 0000 0000

The Right Shift operator


int a =32 ;
a = a >> 1; // a now contains 16
int x = 35;
x = x >> 2; // x contains 8
0010 0011

35

>>2
0000 1000

--------------------------------------------------11111000

-8

>>1
11111100

-4

The Unsigned Right Shift operator


>>> shifts zeros into the high-order bit.

int a = -1 ;
a = a >>> 24;
11111111 11111111 11111111 11111111

// -1 in binary

>>> 24
00000000 00000000 00000000 11111111 // 255 in binary

Boolean Logical Operators


&

Logical AND

Logical OR

Logical XOR

&&

Short- Circuit Logical AND

||

Short- Circuit Logical OR

If you use the || and && forms rather than | and & forms , Java
will not bother to evaluate the right hand operand when the outcome of
the expression can be determined by the left operand alone.
if( denom != 0 && num /denom >10)

// if denom =0 short circuit

if( c = =1 & e++ <100) d= 100;


Single & ensures that the increment operation will be applied whether c
is equal to 1 or not.

Classes and Objects


A Class is a template for an object
Object is an instance of a class.
These characteristics represent a pure approach to objectoriented programming:
1. Everything is an object.
2. A program is a bunch of objects telling each other what to
do by sending messages.
3. All objects of a particular type can receive the same
messages.
4. Tight Cohesion within an object and Loose coupling
among objects.

Each object can satisfy only certain requests.


The requests you can make of an object are defined by its
interface.
The type (class) is what determines the interface.
The idea of type being equivalent to interface is fundamental in
object-oriented programming.

Light lt = new Light(); // The name of the type/class is Light


lt.on(); //requests

The Class of Circles


public class Circle
{
public double x, y; // The coordinates of the center
public double r; // The radius
// Method that returns the area of the circle
public double area( )
{
return 3.14159 * r*r;
}
}

Objects Are Instances of a Class


We can declare variables of that type:
Circle c;
But this variable c is simply a name that refers to a circle object; it
is not an object itself.
In Java, all objects must be created dynamically.
This is almost always done with the new keyword:
c = new Circle();
Accessing Object Data
c.x = 2.0;
c.y = 2.0;
c.r = 1.0;

Using Object Methods


double a = c.area();

How can a method that takes no arguments know what data


to operate on?
In fact, the area() method does have an argument!
The implicit argument is named this,
and refers to "this object -- the Circle object
through which the method is invoked.

Guaranteed initialization with the constructor


If a class has a constructor, Java automatically calls that
constructor when an object is created, before users can even get
their hands on it.
So initialization is guaranteed.
Compiler is responsible for calling the constructor, it must always
know which method to call and hence name of the constructor is
the same as the name of the class.
class Rock {
Rock() { // This is the constructor
System.out.println("Creating Rock");
}
}

public class Circle


{

double x, y, r;
public Circle(double x, double y, double r)
{
this.x = x;
this.y = y;
this.r = r;
}

}
With this new constructor the initialization becomes part of the
object creation step:
Circle c = new Circle(1.414, -1.0,1 .25);

Multiple Circle Constructors


public class Circle {
public double x, y, r;
// Initializing constructors
public Circle(double x, double y, double r)
{ this.x = x; this.y = y; this.r = r; }
public Circle(double r) { x = 0.0; y = 0.0; this.r = r; }
// Copy Constructor
public Circle(Circle c) { x = c.x; y = c.y; r = c.r; }
//Default Constructor
public Circle() { x = 0.0; y = 0.0; r = 1.0; }

this Again
--it can be used from a constructor to invoke one of the other
constructors of the same class.
public Circle(double x, double y, double r)
{ this.x = x; this.y = y; this.r = r; }

public Circle(double r) { this(0.0, 0.0, r); }

public Circle(Circle c) { this(c.x, c.y, c.r); }

public Circle() { this(0.0, 0.0, 1.0); }

Default constructors
As mentioned previously, a default constructor is one without
arguments.
If you create a class that has no constructors, the compiler will
automatically create a default constructor for you
However, if you define any constructors, the compiler will not
synthesize one for you:
class Bush {
Bush(int i) { }
}
Now if you say:new Bush();
the compiler will complain that it cannot find a constructor that
matches

Class Variables
Java uses the static keyword to indicate that a particular variable
is a class variable rather than an instance variable.
That is, that there is only one copy of the variable exists
regardless of the number of instances of the class that are created
It exists and can be used even if the class is never actually
instantiated.
Static Variable Example
public class Circle

static int num_circles = 0; // class var


public double x, y, r; // instance var
public Circle(double x, double y, double r)
{

this.x = x; this.y = y; this.r = r;


num_circles++;

Accessing Class Variables


Because static variables are associated with the class rather than
with an instance, we access them through the class rather than
through the instance

System.out.println("Number of circles : " + Circle.num_circles);

public class Circle


{
public static final double PI = 3.14159;
public double x, y, r;
// ... etc....
}

Besides the static keyword that we've already seen, we use the final
keyword, which means that this variable can never have its value
changed.

static Methods
Class methods are like class variables in a number of ways:
Class methods are declared with the static keyword.
Class methods are invoked through the class rather than
through an instance.
Class methods are the closest Java comes to "global"
methods. Because they must be referred to by the class
name, there is no danger of name conflicts.
Class methods differ from instance methods in one
important way: they are not passed an implicit this
reference.

A Class Method and an Instance Method


public class Circle
{ public double x, y, r;
// An instance method. Returns the bigger of two circles.
public Circle bigger(Circle c)
{

if (c.r > r) return c;


else return this;

}
// A class method. Returns the bigger of two circles.
public static Circle bigger(Circle a, Circle b)
{

if (a.r > b.r) return a;


else return b;

. . // Other methods omitted here. . }

You would invoke the instance method like this:


Circle a = new Circle(2.0);
Circle b = new Circle(3.0);
Circle c = a.bigger(b); // or, b.bigger(a);

And you would invoke the class method like this:


Circle c = Circle.bigger(a,b);

Object Destruction :Garbage Collection


The technique Java uses to get rid of objects once they are no
longer needed is called garbage collection.
The Java interpreter knows what objects it has allocated.

When an allocated object is no longer referred GC knows that it


can destroy it safely, and does so.
GC runs as a low-priority thread, and does most of its work when
nothing else is going on.

The only time the GC must run while something high-priority is


going on is when the interpreter has run out of memory.

Object Finalization
Just as a constructor method performs initialization for an
object, a Java finalizer method performs finalization for an
object.
Garbage collection automatically frees up the memory
resources used by objects.
But objects may hold other kinds of resources, such as file
descriptors or sockets, as well.
The garbage collector can't free these resources up for you, so
you should write a finalizer method that takes care of things
like closing open files, terminating network connections, and
so on.

A finalizer is an instance method (i.e., non-static),


takes no arguments, returns no value (i.e., void), and must be
named finalize().
Ex:
protected void finalize() throws IOException
{

There are some additional things to be aware of about


finalizers:
If an object has a finalizer, that method is invoked before
the system garbage collects the object.
The Java interpreter may exit without garbage collecting
all outstanding objects, so some finalizers may never be
invoked. In this case, though, any outstanding resources are
usually freed by the operating system.
Java makes no guarantees about when garbage collection
will occur, or what order objects will be collected in.

Java access specifiers


public, protected and private are placed in front of each
definition for each member in your class, whether its a data
member or a method.

Friendly or package-private
The default access has no keyword, but it is commonly referred
to as friendly.
It means that all the other classes in the current package have
access to the friendly member, but to all the classes outside of this
package the member appears to be private.

Class Member Accessibility


Accessible to:

public protected

package

private

Same class

yes

yes

yes

yes

subClass in same

yes

yes

yes

no

yes

yes

no

no

yes

no

no

no

package
Subclass in
different package
Non-subclass,
different package

Examples on
Objects as arguments
Object Reference
String & StringBuffer class

Inheritance : Extending a Class


class A
{

int i;

class B extends A
{

int j;

// B is a subclass of A

class I1{
public static void main(String args[])
{

B ob = new B();
ob.i=10;
ob.j=20;

System.out.println("ob's value =" + ob.i +"," + ob.j);


}}

class Rect

private int w,h;


Example 2

void set(int x,int y)


{

w=x;

h=y;

}
int area()
{

return w*h;

void disp()
{
System.out.println("Width =" +w +", Height = " + h + "Area ="
+area());
}
}

class Box extends Rect

int d;
void set(int x,int y,int z)
{

set(x,y);
d=z;

}
void put()
{

disp();
System.out.println("Depth =" + d);

}
}

class I3
{
public static void main(String args[])
{
Box ob = new Box();
ob.set(10,20,15);
ob.put();
}
}

Constructor Chaining
class A
{

int i;

public A()
{ // Implicit call to super(); here.
i = 3; }
}
class B extends A
{
// Default constructor:
public B() { super(); }
}

More on super

Shadowed Variables
class A

int x=10;

class B extends A

int x=20;

class C extends B

int x=30;

void disp()
{

// Variable x in class C.
System.out.println("x in C is :" + x);
// Variable x in class B.
System.out.println("x in B is :" + super.x);
System.out.println("x in B is :" + ((B)this).x);
// Variable x in class A.
System.out.println("x in A is :" + ((A)this).x);

public static void main(String args[])


{
C obj = new C();
obj.disp();
}

Overriding Is Not Shadowing


Method overriding is not like variable shadowing at all:
You can refer to shadowed variables simply by casting an object to the
appropriate type.
You cannot invoke overridden methods with this technique.
Method Overriding versus Variable Shadowing

class A {
int i = 1;
int f() { return i; }
}

class B extends A
{
int i = 2; // Shadows variable i in class A.
int f() { return -i; } // Overrides method f in class A.
}
public class override_test
{

public static void main(String args[]) {


B b = new B();
System.out.println(b.i); // Refers to B.i; prints 2.
System.out.println(b.f()); // Refers to B.f(); prints -2.
A a = (A) b; // Cast b to an instance of class A.
System.out.println(a.i); // Now refers to A.i; prints 1;
System.out.println(a.f()); // Still refers to B.f(); prints

Polymorphism

If you write a function in Java:


void doStuff(Shape s) {
s.erase();
// ...
s.draw();
}
This function speaks to any Shape,
so it is independent of the specific
type of object its drawing and

Circle c = new
Circle();
Triangle t = new
Triangle();
Line l = new Line();
doStuff(c);
doStuff(t);

An object-oriented program contains some upcasting somewhere,


because thats how you decouple yourself from knowing about the
exact type youre working with.
Look at the code in doStuff( ):
s.erase();
// ...
s.draw();
Notice that it doesnt say If youre a Circle, do this, if youre a
Square, do that, etc.
If you write that kind of code, which checks for all the possible
types a Shape can actually be, its messy and you need to change
it every time you add a new kind of Shape.
Here, you just say Youre a shape, I know you can erase( )
yourself, do it and take care of the details correctly.

Dynamic binding

When you send a message to an object even though you dont


know what specific type it is, and the right thing happens, thats
called polymorphism.

The process used by object-oriented programming languages to


implement polymorphism is called dynamic binding.

Abstract base classes and interfaces


Often in a design, you want the base class to present only an
interface for its derived classes.
That is, you dont want anyone to actually create an object of the
base class, only to upcast to it so that its interface can be used.

This is accomplished by making that class abstract using the


abstract keyword.

If anyone tries to make an object of an abstract class, the


compiler prevents them.

This is a tool to enforce a particular design.

You can also use the abstract keyword to describe a method that
hasnt been implemented yet as a stub indicating here is an
interface function for all types inherited from this class, but at this
point I dont have any implementation for it.

An abstract method may be created only inside an abstract


class. When the class is inherited, that method must be
implemented, or the inherited class becomes abstract as well.

Creating an abstract method allows you to put a method in an


interface without being forced to provide a possibly meaningless
body of code for that method.

The interface keyword takes the concept of an abstract class


one step further by preventing any function definitions at all.

The interface is a very useful and commonly-used tool, as it


provides the perfect separation of interface and implementation.

In addition, you can combine many interfaces together, if you wish

Pure inheritance

This can be termed a pure is-a relationship because the


interface of a class establishes what it is.
If you follow the above diagram, derived classes will also have no
more than the base class interface

This can be thought of as pure substitution, because derived class


objects can be perfectly substituted for the base class, and you
never need to know any extra information about the subclasses
when youre using them:

That is, the base class can receive any message you can send to
the derived class because the two have exactly the same
interface.
All you need to do is upcast from the derived class and never look
back to see what exact type of object youre dealing with.
Everything is handled through polymorphism

The extended part of the interface in the derived class is not


available from the base class, so once you upcast you cant call the
new methods

Downcasting and run-time type identification


public class RTTI {
public static void main(String[] args)
{
Useful[] x =
{ new Useful(), new MoreUseful() };
x[0].f();
x[1].g();
// Compile-time: method not found in Useful:
//! x[1].u();
((MoreUseful)x[1]).u(); // Downcast/RTTI
((MoreUseful)x[0]).u(); // Exception thrown
}
}

You might also like