/**
Sandeep Desai s_desai@hotmail.com http://www.thedesai.net
Fundamentals.java
Show all the basic features of Java such as using scalars,
arrays, control structures, strings, assert
You can print this program and read it from top to bottom
Book Reference:
Thinking in Java 3rd Ed
Sun Certified Java Programmer by Kathy Sierra and Bert Bates
To run this program download the J2SDK 1.4.2 or later from java.sun.com
cd \j2sdk1.4.2_05\bin
javac Fundamentals.java
set classpath=.
java Fundamentals
restrictive -> less
private <default> protected public
valid identifiers (variable names) start with letters can have $ _ and digits
transient volatile for variables only
&& || only work with booleans
& | ^ works with int and boolean
Watch for variables with public access
byte b = (byte) 9 + 500; // precision loss error adding byte to int
Note difference between array.length and String.length()
instanceOf is not the same as instanceof
An assignment statement which looks like a comparison if( a=true)...
if System.exit() in try-catch-finally blocks then finally not executed
Uninitialized variable references with no path of proper initialization.
-0.0 == 0.0 is true.
continue must be in a loop( for, do , while ). not in case constructs.
Forward references to variables gives compiler error.
Primitive array types of different types can never be assigned to each other
== gives compiler error if the operands are cast-incompatible.
compiler errors for statement after break or return as unreachable
protected void finalize() throws Throwable
char promoted to int but int not promoted to char
Compiler should see path where final variable initialized
(similar to local variable usage)
String s, StringBuffer sb; if (s==sb) compile time error
if (true ^ false) compiles
static methods can be protected
String, StringBuffer, System, Math, Wrapper classes are final
String, Wrappers immutable
Math not object so not immutable
~3 == -4
loop: int x=0; for(..) if () break loop; // compilation error
*/
// optional but has to be first line, namespace to
// resolve conflicts java converts . to directories
//package foo;
// use internet domain in reverse to guarantee uniqueness
// package com.mydomain.test
/**
Reserved keywords
abstract boolean break byte case catch char class const continue
default do double else extends final finally float for goto if
implements import instanceof int interface long native new package
private protected public return short static strictfp super switch
syncrhonized this throw throws transient try void volatile
while assert
Note const and goto unused reserved keywords
*/
/**
Note assignment left to right
x = 0; a[y] = ++y; // update a[0] and not a[1]
Operator precedence
Mnemonic Operator Type Operators
Ulcer Unary + - ++ --
Addicts Arithmetic and Shift * / % + - << >>
Really Relational > < <= >= == !=
Like Logical and bitwise && || & | ^
C Conditional (ternary) a > b ? c : d
A lot Assignment = += *= %= /=
*/
// All the comments below are picked up the javadoc tool and are used
// for generating documentation, it generates
// cross-referenced HTML pages
// All the @ tags tell javadoc markers
/**
* Javadoc is a way to document code
* Embedd <em>html</em>
* @author author info
* @see classname
* @see fully-qualified-classname#method-name
* @since
* @version
* @throws class-name descriptions exceptions thrown by class or method
* @deprecated cause Java compiler warnings that this class or method may
* be removed
* {@docRoot}
* {@inheritDoc}
* method specific javadoc are @throws, @deprecated @param and @return
* @param parameter-name description
* @return description
**/
public class Fundamentals {
// public static means a function accessible from anywhere (global function)
// narrow to widest byte short int long float double
public static void primitives() {
// Primitive data types all data types are signed,
// no unsigned data type except char
boolean ab1; // Initialize to false can be true or false
boolean ab2 = true;
boolean ab3, ab4;
char ac = 'a'; // 16-bit Unicode range 0 to 2^16-1
char ac2 = '\uaaaf'; // Unicode hex 32-bit character
byte ab = 2; // 8-bit range -128 to +128
ab = (byte)257; // ab becomes 1 as overflow is 257 % 256 (range of byte)
short as1 = 5; // 16-bit range 2^15-1 +2^15+1 (-32768 to 32767)
short as2 = 6;
// without typecast compilation error about loss of precision
short as3 = (short) (as1 + as2);
as2 += as1; // OK
int ai1 = 1; // range -2^31 to +2^31 (-2147483648 to 214783467)
int ai2; // Initialized to zero
int ai3 = 0x2f; // Hexadecimal (lowercase)
int ai4 = 0X2F; // Hexadecimal (uppercase)
int ai5 = 0177; // Octal (leading zero)
int ai6 = 'c'; // Valid
int ai7 = ai3 + ai4; // No compilation error for overflow
long al = 2L; // 64-bit range -2^63 to +2^63-1
float af = 0.5f; // 32-bit
// Will not compile as all fractions are double by default
//float af2 = 0.3;
double ad = 47e47d; // 47^47
double ae = 10e3d; // 10000
final int fi = 2; // Constant value of f cannot be changed
//ai7 = fi++; // error cannot increment final
int b = -2; // Negative twos complement, flip all bits and add 1
// + - * / % (modulus)
ai1 = 2 + 2; ai1 = 4 * 2;
ai1 += 2; // same as ai1 = ai1 + 2;
int x = 17 % 4; // Result is 1 which is remainder
x = -10 % 4; // Result is -2 which is remainder
x = 10 % -4; // Result is 2 which is remainder
++x; // add 1 to x
--x; // subtract 1 from x
x = 1;
x = x++; // still 1 execution left to right
int y = x++; // assign first and then increment
// bitwise operators work on boolean and int
// & bitwise and
// | bitwise or
// ^ bitwise XOR (true if bits are different else false)
// 1 ^ 1 is 0 and 1 ^ 0 is 1
// ~ bitwise negation
// << bitwise left shift (same as mulitply by 2 to power of shift)
// >> bitwise right shift (same as divide by 2 to power of shift)
// >>> unsigned right shift (zero filled right shift)
// Negative number are two complement -2 will be ~2 + 1
System.out.println("Hex of -2=" + Integer.toHexString(-2));
ai1 = 1;
ai1 = ai1 << 1; // left shift by 1 result is 2 (always add 0 to right)
ai1 = ai1 >> 33; // is ai1 >> 1 as Java does 33 % 32
ai1 = ai1 >> 32; // is do nothing
ai1 = 8; // 01000
ai2 = ai1 >> 2; // result if 2 (0010) (same as ai2 = ai1 / (2^2)
ai1 = 0x80000000; // 1 followed by 31 0 hex values of Integer.MIN_INTEGER
ai2 = ai1 << 1; // result 0 as left shift drops the first 1 (does not wrap)
ai1 = -1;
ai2 = ai1 >> 1; // Number remains negative as 1 is shifted in from left
ai1 = -1;
ai2 = ai1 >>> 1; // Number turns positive as we shift in 0 from left
System.out.println("-1 >>> 1=" + ai2); // 2147483647
ai2 = ai1 >> 34; // becomes ai2 >> 2 (34 % 32)
ai2 = ai1 >> 32; // value will not change
ai1 = 1;
ai1 = ai1 << 31;
ai1 = ai1 >> 31;
System.out.println(" 31 shift " + ai1); // -1
ai1 = 5;
System.out.println("bitwise negation ~5=" + ~ai1); // -6
ai2 = 3;
// ternary operator
ai1 = (ai2 == 3) ? 4 : 5; // if true set ai1 to 4 else 5
ai1 = (int) 4.3; // ai1 will be 4
ai1 = Integer.MIN_VALUE;
int bi1 = -ai1; // value is Integer.MIN_VALUE because of overflow
long l = 130L;
// result is -126 as left most bits beyond 8th bit are trimmed
short s = (short) l;
long al5 = ai1; // implicit cast widening
// explicit cast required because of possible loss of precision
ai1 = (int) al5;
//byte b = (byte) 9 + 500; // compile error
b = (byte)( 9 + 500); // OK
int c = 0;
try { int d = 3 / c; }
catch (ArithmeticException e)
{ System.out.println("Runtime exception " + e); }
try { int d = 3 % c; }
catch (ArithmeticException e) { }
float afz = 3f / 0; // No exception
// Note && is short circuited so if first part is false,
// it does not evaulate 3/0
// hence no runtime error
boolean b5 = ((3 < 2) && (1 < (3 / 0)));
// since first part true don't evaluate second part
b5 = ((3 > 2) || (1 < (3 / 0)));
// Note here both b7 and b8 evaluated
//divide by zero exception thrown
try { boolean b9 = true | (1 < 3/ 0); }
catch (ArithmeticException e)
{ System.out.println("/ by zero because of |");}
// logical operators && || !
boolean b2 = ai1 > 0 && ai1 < 5;
// b2 = ~b2; //compilation fails
b2 =!b2; // runs
}
// Java checks that an array index is in range, if not it reports an error
// Array is an instanceof Object
public static void arrays() { // void means returns nothing
// Array of 3 elements with all elements initialized to zero
int[] afoo1 = new int[3];
Object o = afoo1; // Array is an object
int [] a,b; // both a and b arrays
int c[],d; // a[] array and b is int
// Array of 2 elements afoo2.length returns the length of an array
int[] afoo2 = { 3, 5 };
// **** int[2] = {4, 5} compilation error
// Java will report index out of range error (throw exception)
//afoo2[3] = 1;
int[] bref = afoo1; // bref points to afoo1
int[][] a1 = { { 1, 2, 3}, {4, 5, 6} }; // 2 Dimensional array
short[] ashort3;
//ashort3 = afoo1; // compilatin error incompatible types int[] and short[]
afoo2[0] = 4;
// class Car {} class Honda extends Car
// Honda[] h; Car[] c = h; // OK
// h = c; // compile error
if (afoo2 instanceof Object) System.out.println("int[] instanceof object");
// afoo2.length is array length
System.out.println("afoo2 length " + afoo2.length);
int p[] = { 4,5};
int q = 1;
p[q] = q = 0;
// p[1] = 0, q = 0
// evaluated left to right
int[] ia = null;
char[] ca = null;
// Cannot cast primitive array from type to another
//ia = (int[]) ca; // will not compile
}
/**
String is not a primitive datatype it is a full fledged Java Object
String is immutable, once set cannot be modified, have to create
new String objects
String class is final cannot be overriden
JVM tries to reuse String reference if the String data is same,
hence String immutable and class final
Strings stored in String constant pool so that when new String
created Java checks in the String constant pool and reusesthe String
String("abc")
String(String orig)
String(StringBuffer)
String(char[] values)
contentEquals(StringBuffer sb)
toLowerCase() // will return the same string if no modification required
boolean endsWith(String suffix)
equalsIgnoreCase(String anotherString)
indexOf(char) indexOf(char ch, int fromIndex)
indexOf(String str) indexOf(String str, int fromIndex)
lastIndexOf
startsWith(String str) startsWith(String str, int offset)
substring(int startIndex)
substring(int startIndex, int endIndex) // endIndex count 1 from start
trim()
static valueOf() all primitive types
static valueOf(char[] ch)
static valueOf(char[] ch, int start, int end)
StringBuffer final does not override equals or hashCode
methods are syncrhonized
StringBuffer(String s)
append() // all primitive data types, String, StringBuffer, Object
delete(int start, int end)
insert(int offset,...) like append
delete()
indexOf(String str)
indexOf(String str, int fromIndex)
lastIndexOf(String str)
lastIndexOf(String str, int fromIndex) // search backwards fromIndex
replace(int start, int end, String str)
setLength(int length) // truncate if less else fill with '\u0000'
substring(int start)
substring(int start, int end)
*/
public static void strings() {
String sa = "Hello"; // String is not a primitive data type
String sb = "Hello"; // sa == sb
if (sa == sb) { } // true as Strings are stored in
sa = new String("Hello");
sb = new String("Hello");
if (sa == sb) {} // false because of new
sb = sa;
sb = sa + " World World"; // concat string
int ai = 10;
// Automatic Integer to String coversion
sb = sa + ai + 4; // Hello World World104
sb = sa + (ai + 4); // Hello World World14
sb = ai + 4 + sa; // 14HelloWorld
// Not above + creates a new String so sa is not modified
sb = sb.trim(); // trim white space
String s1 = "abc";
// constructs new string internally and returns reference
s1 = s1.concat("def");
// The next two statements create 3 string objects
s1 = new String("abc");
s1 = s1 + sb;
//****** Imutability examples
s1.concat("ghi"); // Does not modify s1
s1.toUpperCase(); // Does not modify s1
s1 = s1.toUpperCase();
s1 += "z"; // same as concat
//b.compareTo("Hello World"); // used for sorting
boolean b = sb.equals("Hello World World");
b = sb.equalsIgnoreCase("hello world world"); // returns true
char c = sb.charAt(4); // returns 'o'
b = sb.endsWith("World");
int index = sb.indexOf("World"); // returns 6
String aa = "one two one two";
int lastIndex = sb.lastIndexOf("one", 10); // searches backward from index 10
// index = sb.lastIndexOf("World", startIndex);
// ***** String has length() method and Array has length attribute
int length = sb.length(); // 17
b = sb.matches("^Hello.*"); // regular expression match returns true
// ([{\^$|)?*+. regular expression metacharacters
sb.replaceAll("^Hell.?", "Ola"); // ???? how does this work
String[] sp = sb.split(" "); // split string based on regular expression
String lowerCase = sb.toLowerCase();
String upperCase = sb.toUpperCase();
sb = sb.trim(); // trim whitespaces
// convert int to string, also takes float, decimal etc
String str = String.valueOf(5);
sa = "abcdef";
sa = sa.replace('b', 'd');
sa = "abcdef";
sa = sa.substring(1); // begin -> "bcdef"
sa = "abcdef";
// Note end not zero based
sa = sa.substring(1, 3); // begin, end returns "bc"
System.out.println("After substring sa=" + sa);
// StringBuffer not immutable
StringBuffer sbuf = new StringBuffer("hello");
sbuf.append(" ").append("world"); // can chain methods because of mutability
sbuf.append(3); // append takes boolean, char, double, float, int long
sbuf.insert(6,"to "); // offset, string -> "hello to world3"
System.out.println("sbuf.insert=" + sbuf.toString());
sbuf = new StringBuffer("abc");
sbuf.reverse();
String s = "Hello,World";
java.util.StringTokenizer st = new java.util.StringTokenizer(s, ",");
while (st.hasMoreTokens()) { String token = st.nextToken(); }
}
/**
Math class is final
Math class has all static methods
0.0 == -0.0
-1.0/0.0 == Infinity
int Math.round(float)
double Math.random() between >=0 and < 1
long Math.round(double) // only method to return int
Math.floor() and Math.ceil() return type double
All comparisons involving NaN and a non-Nan always result in false.
Default type of a numeric literal with a decimal point is double.
integer (and long ) operations / and % can throw ArithmeticException
while float / and % will never, even in case of division by zero.
double abs(double a)
float abs(float a)
int abs(int a)
long abs(long a)
double acos(double a) // Returns the arc cosine of an angle, in the range of -pi/2 through pi/2.
double asin(double a)
double atan(double a)
double atan2(double y, double x) // Converts rectangular coordinates (x, y) to polar (r, theta).
double ceil(double a) // Returns the smallest (closest to negative infinity) double value that is
// not less than the argument and is equal to a mathematical integer.
double cos(double a) // Returns the trigonometric cosine of an angle.
* double exp(double a) Returns Euler's number e raised to the power of a double value.
double floor(double a) // Returns the largest (closest to positive infinity)
// double value that is not
// greater than the argument and is equal to a mathematical integer.
double IEEEremainder(double f1, double f2) // Computes the remainder operation on two arguments as
// prescribed by the IEEE 754 standard.
double log(double a) // Returns the natural logarithm (base e) of a double value.
double max(double a, double b) takes float, long, int
double min(double a, double b) takes float long int
double pow(double a, double b)
double random() // >= 0 and < 1
double rint(double a) // Returns the double value that is closest in value to
// the argument and is equal to a mathematical integer.
long round(double a) // Returns the closest long to the argument.
int round(float a) // Returns the closest int to the argument.
double sin(double a) // Returns the trigonometric sine of an angle.
double sqrt(double a) // Returns the correctly rounded positive square root of a double value.
double tan(double a) // Returns the trigonometric tangent of an angle.
double toDegrees(double angrad) // Converts an angle measured in radians to an
// approximately equivalent angle measured in degrees.
double toRadians(double angdeg) // Converts an angle measured in degrees to an
// approximately equivalent angle measured in radians.
*/
public static void math() {
//
double pi = Math.PI;
double e = Math.E;
float p_i = Float.POSITIVE_INFINITY; // e.g result of 16d / 0.0
float n_i = Float.NEGATIVE_INFINITY;// e.g result of 16d / -0.0
double notanum = Double.NaN; // 0.0d /0.0
if (notanum != notanum) {} // not equal
if (Double.isNaN(notanum)) {} // true
if (Double.isNaN(Math.sqrt(n_i))) {} // true
if (Double.isNaN(Math.sqrt(-16d))) {} // true
int x = Math.abs(-99); // 99 takes long, float, double
x = Math.abs(-0); // 0 takes long, float, double
// still returns Integer.MIN_VALUE as positive number does not fit
// 0x80000000 = -2147483648
x = Math.abs(Integer.MIN_VALUE);
System.out.println("abs(Integer.MIN_VALUE)=" + x);
// ceil and floor take double only
double d = Math.ceil(3.1); // returns double as 4.0
d = Math.ceil(-3.1); // returns double as -3.0
d = Math.floor(3.1); // returns double as 3.0
d = Math.floor(-3.1); // returns double as -4.0
// Math.round returns int or long
long al = Math.round(1.6); // 2 adds 0.5 and does a truncate
al = Math.round(-1.5); // -1 adds 0.5 and does a truncate
al = Math.round(1.5); // 2 takes float and double
al = Math.round(1.4); // 1
x = Math.max(1, -1); // can handle int, long, float, double
x = Math.min(1, -1); // can handle int, long, float, double
double r = Math.random(); // r >= 0.0 && r < 1
r = Math.sin(Math.toRadians(90.0)); // takes double as parameter
r = Math.cos(Math.toRadians(90.0)); // takes double as parameter
// cos() tan()
r = Math.toDegrees(Math.PI * 2.0); // 360.0 takes double returns double
// 6.283185 (Math.PI*2) takes double returns double
r = Math.toRadians(360.9);
r = Math.sqrt(9); // 3 takes double returns double
}
/**
All primitive datatypes have wrapper objects for providing addtional functionality
All wrapers immutable and final
void, Void // can be instantiated
char Character,
int Integer extends Number
long Long extends Number
float Float extends Number
double Double extends Number
byte Byte extends Number
short Short extends Number
create using new or valueOf
abstract class Number has byteValue(), shortValue() etc
string to number can throw runtime NumberFormatException
Character does not have any of the below
// All Wrappers
toString()
static String toString(<primitive>) // convert to primitive
static Wrapper valueOf(String s)
static <primitive> parseXXX(String s)
// only Integer and Long
static String toHexString(int i)
static String toBinaryString(int i)
static String toOctalString(int i)
static int/long decode(String s) can handle octal, hex etc
static Integer/Long valueOf(String s, radix)
static int Integer.parseInt(String s, int radix)
// only Integer
static Integer Integer.getInteger(String nm) // reads system property
Long a = new Long(10); int b = new Integer(10);
if (a.equals(b) {} // false
*/
public static void wrappers() {
Character c = new Character('c'); // only one constructor
Boolean bw = new Boolean(true); // takes
bw = new Boolean("TrUe"); // case insensitive String true or false
//if (bw) {} // won't compile
Integer iw = Integer.decode("5"); // String to integer
iw = Integer.valueOf("101");
iw = new Integer("42");
// valueOf and parseXXX take radix valueOf
// returns Wrapper and parseXXX primitive
iw = Integer.valueOf("101", 2); // in binary
// can throw NumberFormatException (RuntimeException)
int ai = Integer.parseInt("123");
Float fw = new Float("3.2f");
String s = Integer.toString(254, 16); // int to hex string
s = Integer.toOctalString(254); // toXXXString Hex,Octal,Binary
s = fw.toString(); // All wrappers implement toString()
s = Float.toString(3.2f);
ai = iw.intValue(); // xxxValue Wrapper conversion to primitive
byte ab = iw.byteValue();
// equals checks if same type e.g
iw = new Integer(42);
// Short sw = new Short(42); // will not compile as 42 is int
Short sw = new Short((short)42);
if (iw.equals(sw)) {} // false
// Immutable arbitrary-precision integers
java.math.BigInteger bi = new java.math.BigInteger("123448273592");
java.math.BigDecimal bd = new java.math.BigDecimal("123.56728347");
}
public static void wrapperArray() {
Integer[] ss = new Integer[3];
Integer[] s2 = { new Integer(1), new Integer(2) };
Integer[] s3 = new Integer[] { new Integer(1), new Integer(2) };
Integer[][] a;
a = new Integer[2][];
a[0] = new Integer[2];
a[0][0] = new Integer(1);
}
/**
local variables have to be initialized before use
int x;
int k=1;
if () x=1; else x=2; ++x; // OK
if () x=1; if () x=2; ++x; // compiler error
switch (k) { case 0: default: x =2; } ++x; //OK
for (int i=0,j=0; i < 5; ++i) {} // OK
int j=0; for (int i=0,j=0; i < 5; ++i) {} // Compiler error j declared twice
*/
public static void controls() {
int i = 0;
int j = 0;
if (i == 0) { }
else { }
if (i == 0) { }
else if (i == 1) { }
else { }
if (i == 0 && j == 0) { }
// && is logical and || is logical
if (!(i == 0)) { }
// ! is negation
if (i != 0) { }
if (i != 0)
;
else { }
// if (i = 1) {} will not compile
boolean b = false;
// Not = insteadof == this will compile and run OK
// requirement is that expression in () should evaluate to boolean
if (b = true) { }
// ternary operator short cut way of writing an if
int r = (i == 0? i * 3: i * 5);
// while (boolean expression) can't do while (int x = 0) {}
while (i < 3) { ++i; }
do { --i; } while (i > 0);
do { System.out.println("do-while executed once"); } while (false);
// i value never reaches 3 because of break
// break must be in loop or switch else compile error
r = 0;
for (int k = 0,z = 0; k < 3; ++k,z++) {
if (k == 2)
break;
// break out of loop
++r;
}
for (int k = 0; k < 1; System.out.println("for iteration")) {
++k;
}
// // Note continue must be in loop else compile error
for (i = 0; i < 3; i += 2) {
if (i == 2)
continue;
// skip
++r;
}
// we are naming these loops here
outerloop:
for (i = 0; i < 2; ++i) {
innerloop:
for (j = 0; j < 2 ; ++j) {
if (i == 1 && j == 1)
break outerloop;
// breaks out of both for loops
if (j == 0)
continue outerloop;
}
}
// will reach here on break outerloop
// will run 3 times
for (i = 0; i < 3 ; ++i) {
here:
if (i == 1)
break here;
}
r = 0;
final int x = 2;
/**
* switch takes int, short, byte, char
* case has to have a final compile time constant
* case cannot have duplicates
* if switch has byte, case values should be less than 128
* else compile time error
*/
switch (r) {
// if break not specified values will be 7 as code
// is executed till break found
case 0: r = 5; break;
case 1: r = 7;
//case 1: r = 20; break; // cannot repeat case
default: --r; break;
// default can be in the middle or top or end also
case x: r = 9; break;
case x + 7: r = 9; break;
case 'a': r = 7;
}
byte by = 5;
switch (by) {
case 4:
case 'A': break;
}
String s = null;
// short circuited expression since s != null s.length() is not evaluated
if (s != null && s.length() > 2) {
// 'A' OK as it fits in byte
// short circuited expression since s != null s.length() is not evaluated
}
}
/**
assertions disabled by default
compile javac -source 1.4 foo.java
runtime assert disabled by default
Can also be programatically enabled or disabled using ClassLoader
java -ea foo
-da -disableassertions -ea -enableassertions
-dsa -disablesystemassertions -esa
java -ea -da:com.foo.bar blah
disable assertion for com.foo.bar package and subpackages
java -ea -da:com.foo... blah
assert (true boolean expression) if false throw AssertionError
can be any expression that returns value after : (not allowed void)
Assert best practices
use in private methods not in public
OK to put assert postconditions at end of public method
do not use in switch default
expresion after : should not cause side effects
sometimes OK to throw AssertionError explicitly
AssertionError(all primitivet types)
does not take String as constructor
*/
private static void assertCheck(int n) {
assert (n >= 0) : "Negative number => " + n;
assert (n <= 10);
boolean b = n <= 5;
assert b;
assert b: n++; // bad causing side effect
//assert (n <= 15) : foovoid(); will not compile as foo returns void
}
static void foovoid() {}
// required for passing to inner class also in Thread
// final can be added or removed for overridden methods
// parameters to method are pass by value, so modification
// inside method do not affect caller
// Value of caller not changed only local copy changed
public static void foo1(final int x) { }
public static void foo2(int x) { x=5; }
// caller will see the appended value
public static void foo3(StringBuffer s) { s.append("s"); }
int size = 7;
// we are shadowing instance variable with local variable
// note instance size will not be modified
public static void foo4(int size) { size = 8; }
// method return types
static Object ret1() { int[] x = new int[1]; return x; }
void ret2() { /* return "blah"; // compile error */ }
class foo {} class bar extends foo {}
foo ret3() { return new bar(); } // will compile OK
// cannot make static -> class, constructor interface, inner classes,
// inner class methods, local variables
transient int x; // do not serialize
volatile int y; // sync private copy in thread with master copy
// Local variables -> final
// Variables non local -> final public protected private static transient volatile
// Methods final public protected private abstract
// Concrete Methods synchronized strictfp native static
public static void methods() {
int x = 1;
foo1(x); // x will remain 1 after call
foo2(x);
System.out.println(x);
StringBuffer s1 = new StringBuffer("Hello");
foo3(s1); // contents of s1 can be modifed
}
/**
new always allocates memory on the heap
Java uses Garbage collection no need to do free
Garbage Collecter varies by JVM implementation
May use mark and sweep or reference counting
Object is marked for garbage collection when no live thread
has reference to the object
Each Java app has one or more threads
Note that until application exits main() thread is running
finalize() may never be called
finalize() method only called once
finalize() exceptions ignored and garbage collection canceled
*/
public static void memory() {
System.gc(); // hint to JVM to run garbage collector. May or maynot run
// Ways to make object eligible for garbage collection
String s1 = new String("s1");
s1 = null; // s1 now marked for garbage collection
s1 = new String("s1");
String s2 = new String("s2");
s1 = s1; // s2 string eligible for garbage collection
// we can also have islands of isolation where we have objects
// refering to each other but no objects refering to them
// at the end of method local variables eligible for garbage collection
System.out.println( "TotalMemory (bytes)=" + Runtime.getRuntime().totalMemory()
+ ",FreeMemory=" + Runtime.getRuntime().freeMemory());
}
public static void foo9(char c) {System.out.println("char");}
public static void foo9(float f) {System.out.println("float");}
public static void foo9(double d) {System.out.println("double");}
public static void casting() {
System.out.println("**** casting ****");
int i = 3;
foo9(i); // calls foo9(float)
}
/**
can handle primitives and Strings concatenated by +
System.out.println("" + new Object()); // compilation error
*/
public static void print() {
System.out.println("*** System.out.println ***");
// System.out.println only converts primitives
//System.out.println("" + new Object()); // compilation error
int i=0;
float j=0;
System.out.println(i + j); // prints 0.0
// will call Object.toString()
System.out.println(new Object());
Object a = new String("A");
Object b = new java.util.ArrayList();
Object c = new java.util.Vector();
System.out.println("" + b + c);
//System.out.println(b + c + ""); // compilation will fail
}
// We can name the args variables anything
public static void main(String[] args) {
primitives();
strings();
arrays();
wrappers();
math();
controls();
methods();
memory();
print();
casting();
assertCheck(-1);
}
}