Advanced Programming
SUT • Spring 2019
public class Dog {
private String name;
public void setName(String name) {
this.name = name;
}
public void bark() {
System.out.println("Hop! Hop!");
}
}
public class Main {
public static void main(String[] args) {
// Dog
Dog dog = new Dog();
dog.setName("Fido");
dog.bark();
}
}
Remember : an object has state, behaviour and identity
Each object is stored in memory
Memory address ≈ object identity
Memory content = object state
The behaviour of an object is declared in its class
Class declaration is also stored in memory
But class declaration is stored once for each class
For each object a separate piece of memory is needed
To store its state
new operator creates a new object from the specified type
Returns the reference to the created object
String string = new String();
Dog dog = new Dog();
Rectangle rectangle = new Rectangle();
Remember C++ pointers
When you declare an object, you declare its reference
Exception: ?
Primitive types
Primitive types are not actually objects
They can not have references
Java references are different from C++ pointers and references
String s;
Rectangle rectangle;
This code will not create an object:
It just creates a reference
This is a key difference between Java and C++
You can not use “s” variable
“s” is null
null value in java
You should connect references to real objects
How to create objects?
new
String s;
Rectangle rectangle;
new creates a piece of memory
Returns its reference
Where is the piece of memory?
In Heap
Where is the Heap?
Later…
public class Main {
public static void main(String[] args)
// Array in Java
Integer[] integers;
Dog[] dogs = new Dog[5];
int n = 10;
float[] float_numbers = new float[n];
}
}
public class Main {
public static void main(String[] args) {
// Primitive-Type Array Sample
int[] array = new int[10];
int[][] twoDimArray = new int[5][];
twoDimArray[0] = new int[7];
twoDimArray[1] = new int[12];
int[][] matrix = new int[5][7];
}
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// Array Samples
Scanner scanner = new Scanner(System.in);
int arrayLength = scanner.nextInt();
String[] names;
names = new String[arrayLength];
for (int i = 0; i < names.length; i++) {
names[i] = scanner.next();
}
System.out.println(names[names.length - 1]);
}
}
There is three type of variable in this code
array: reference
array[i]: references
Initial value: null
array[i]: objects
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
scanner = new Scanner(System.in);
int arrayLength = scanner.nextInt();
String[] names;
names = new String[arrayLength]
for (int i = 0; i < names.length; i++) {
names[i] = scanner.next();
}
}
}
public class Student {
private String name;
private Long id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
static void studentCreation() {
Student[] students = new Student[10];
for (int i = 0; i < students.length; i++) {
students[i] = new Student();
students[i].setId((long) i);
}
}
Allocated memory should be released
delete operator in C++
Problems with delete in C++
Error-Prone
Segmentation Fault!
Sometimes causes memory leak
a program consumes memory but is unable to release it
Complicated in many situations
You don’t need it in java
Garbage Collection
public class Student {
private String name;
private long ID;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public long getID() { return ID; }
public void setID(long id) { ID = id; }
public static void main(String[] args){
Student[] s = new Student[10];
for(int i = 0; i < 10; i++){
s[i].setID(i + 10000);
}
System.out.println(s[5].getID());
}
}
Object Abstraction
Abstract Data Type
Object Declaration (Class Declaration)
public class Person {
private String name;
private int age;
public void run(){...}
public void talk(){...}
}
Object Instantiation
new
public static void main(String[] args){
Person JafarAgha = new Person();
JafarAgha.setAge(50);
JafarAgha.setName("Jafar");
JafarAgha.talk();
Person AzamKhanoom = new Person();
}
5
...
j
a
f
a
r
Call by value
Call by reference
Call by pointer
Java style: Call by passing value of references!
Let’s see!
public static void main(String[] args){
X variable = new X();
f(variable);
}
static void f(X parameter){
...
}
/*
* static void f(){
* X parameter = variable;
* }
*
*/
Call by value
Call by pointer
Call by reference
void cppMethod(Person byValue, Person* byPointer,
Person& byReference){
byValue.name = "ali";
byPointer->name = "ali";
byReference.name = "ali";
}
Person p1, p3; Person* p2;
p2 = new Person(…);
cppMethod(p1, p2, p3);
Does p1.name change?
no
Does p2->name change?
yes
Does p3.name change?
yes
void cppMethod(Person byValue, Person* byPointer,
Person& byReference){
Person* newP = new Person;
byValue = *newP;
byPointer = newP;
byReference = *newP;
}
cppMethod(p1, p2, p3);
Does p1 change?
no
Does p2 change?
no
Does p3 change?
yes
Java has no pointer
Java references are different from C++ references
Java references are more like C++ pointers
than C++ references
A Java reference is something like a limited pointer
public void javaMethod(Person first, Person second, int number){
first.age = 12;
number = 5;
Person newP = new Person();
second = newP;
}
javaMethod(p1, p2, myInt);
Does p1.age change?
yes
Does myInt change?
no
Does p2 change?
no
In java, primitive variables are passed to methods by their values
Reference values are passed by their reference values.
public class Swap {
public static void main(String[] args) {
int a = 4, b = 5;
badswap(a, b);
System.out.println(a + " " + b);
}
static void badswap(int a, int b) {
int tmp = a;
a = b;
b = tmp;
}
}
public class Swap {
public static void main(String[] args) {
String a = "4", b = "5";
badswap(a, b);
System.out.println(a + " " + b);
}
static void badswap(String a, String b) {
String tmp = a;
a = b;
b = tmp;
}
}
void cpp_swap(int& var1, int& var2){
int temp = var1;
var1 = var2;
var2 = temp;
}
int main() {
int a = 5;
int b = 4;
cpp_swap(a, b)
}
Everything is passed by value
Primitive-types are passed by value
References are passed by value
But not the value of the object
the value of the reference
If you want to pass something by reference…
Wrap it in an object
And make it mutable
public class Swap {
public static void main(String[] args) {
IntWrapper a = new IntWrapper(4), b = new IntWrapper(5);
swap(a, b);
System.out.println(a.value + " " + b.value);
}
static void swap(IntWrapper a, IntWrapper b) {
int tmp = a.value;
a.value = b.value;
b.value = tmp;
}
}
class IntWrapper {
public int value;
public IntWrapper(int value) {
this.value = value;
}
}
public class ForEach {
public static void main(String[] args) {
int[] array = new int[4];
for (int i = 0; i < array.length; i++) {
array[i] = i;
}
print(array);
}
static void print(int[] array) {
for (int item : array) {
System.out.println(item);
}
}
}
In for each expression, each element is assigned to another variable
If X is a primitive type, element values are copied into item variable
public class ForEach {
public static void main(String[] args) {
X[] array = new X[4];
for (int i = 0; i < array.length; i++) {
X item = array[i];
}
for (X item: array) {
}
}
}
package com.company;
public class VarArgs {
static void print(String... params) {
String[] array = params;
System.out.println(array.length);
for (String s : params) {
System.out.println(s);
}
}
public static void main(String[] args) {
print("sallam", "taghai");
print("Sallam");
print();
}
}
Sometimes they are called vararg
Varargs are actually arrays
public static void main(String[] args){
int[] array = new int[4];
for (int i = 0; i < 4; i++){
array[i] = i;
}
f(array);
System.out.println(array[2]);
}
private static void f(int[] a){
a[2] = 0;
for (int i: a){
i = 5;
}
a = new int[10];
a[2] = 1;
}
Registers
Stack
Heap
Constants
Non-RAM
Fastest
Inside the CPU
Number of registers are limited
You don’t have direct control over registers
In assembly you have direct access to registers
C and C++ have access to this storage to some extent
In RAM
Slower than register but less limited
Mechanism of function call in CPU
Stack pointer (cp)
Support of CPU
Java references are (usually) placed on stack
Primitive data types are also (usually) located in stack
Java compiler must know the lifetime and size of all the items on the stack
Java objects themselves are not placed on the stack
C++ allows allocation of objects on the stack
E.g. this code creates an object on the stack
Person p;
In C++ it creates an object on the stack
In Java it creates only a reference on the stack
The actual object will be on Heap
C++ allows arrays of known size on stack
Java does not!
Some information are available at compile time
Stack elements should be specified in compile time
So C++ allows these variables on stack:
int array[10];
Person p;
Some information are not available at compile time
So variable length variables can not be on stack
If n is a variable “int array[n] “ is not allowed in C++
Java is simple! No object on stack!
This is a general-purpose pool of memory
Also in the RAM area
All Java objects live here
The compiler doesn’t need to know the length of the variables
new operator = the storage is allocated on the heap
The objects may become garbage
Garbage collection
The heap is split up into generations
The young generation
stores short-lived objects that are created and immediately garbage collected
The Old generation
Objects that persist longer are moved to the old generation
also called the tenured generation
The permanent generation (or permgen)
is used for class definitions and associated metadata
new is not efficient for these small variables
int a;
char ch;
In these cases, automatic variable is created
that is not a reference
The variable holds the value directly
It’s placed on the stack
Much more efficient
When these primitives are not stored on stack?
When they are inside an object
Used to represent primitive values when an Object is required
All of them are immutable
Primitive Type | Wrapper Class |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
chat | Character |
boolean | Boolean |
public class Wrapper {
public static void main(String[] args) {
Integer i = new Integer(2);
Integer j = new Integer(2);
System.out.println(i == j);
//Prints false. Why?
i = j; //Reference Assignment
i = 2; //OK. A new shortcut in Java5+
Long l = 2; //Syntax Error. Why?
Long l = 2L; //OK
l = i; //Syntax Error. Why?
}
}