0% found this document useful (0 votes)
4 views

Part 4 - Java programming Advanced 2

The document provides an advanced overview of Java programming concepts, focusing on generics, nested classes, enums, concurrency, functional-style programming, the Date Time API, and JVM internals. It covers essential topics such as generic types, bounded type parameters, wildcards, and the implications of type safety and invariance. Additionally, it discusses the use of generic methods and their syntax, emphasizing the importance of compile-time type safety in Java.

Uploaded by

montadhr.social
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

Part 4 - Java programming Advanced 2

The document provides an advanced overview of Java programming concepts, focusing on generics, nested classes, enums, concurrency, functional-style programming, the Date Time API, and JVM internals. It covers essential topics such as generic types, bounded type parameters, wildcards, and the implications of type safety and invariance. Additionally, it discusses the use of generic methods and their syntax, emphasizing the importance of compile-time type safety in Java.

Uploaded by

montadhr.social
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 70

Java programming

Advanced 2
1. GENERICS ................................................................................................................................................. 4

1.1. GENERIC TYPE / PARAMETRIZED TYPE .............................................................................................................. 5


1.2. BOUNDED TYPE PARAMETER......................................................................................................................... 7
1.3. UNBOUNDED WILDCARD ............................................................................................................................. 9
1.4. INVARIANCE............................................................................................................................................. 10
1.5. GENERIC METHODS .................................................................................................................................. 11
1.6. BOUNDED WILDCARDS .............................................................................................................................. 14
1.6.1. Motivation .................................................................................................................................. 14
1.6.2. Upper bounded wildcards ........................................................................................................... 14
1.6.3. Lower bounded wildcard ............................................................................................................. 15
1.7. GENERICS RESTRICTIONS ............................................................................................................................ 16

2. NESTED CLASSES .................................................................................................................................... 17

2.1. NON STATIC MEMBER CLASSES ................................................................................................................... 19


2.2. ANONYMOUS CLASSES ............................................................................................................................... 20
2.3. LOCAL CLASSES ........................................................................................................................................ 22
2.4. STATIC MEMBER CLASSES .......................................................................................................................... 23
2.5. VARIABLE SCOPE WITH NESTED CLASSES ....................................................................................................... 24

3. ENUMS .................................................................................................................................................. 24

3.1. ENUM CLASS ........................................................................................................................................... 26


3.2. ENUMS WITH STATE BEHAVIOR ................................................................................................................... 26
3.3. NESTED ENUMS ........................................................................................................................................ 26
3.4. ENUMS WITH CONSTANT-SPECIFIC BEHAVIOR ................................................................................................ 27

4. CONCURRENCY (MULTI-THREADING) ..................................................................................................... 29

4.1. THREADS................................................................................................................................................. 29
4.1.1. Introduction ................................................................................................................................ 29
4.1.2. Threads ....................................................................................................................................... 30
4.2. RACE CONDITION ..................................................................................................................................... 33
4.3. SYNCHRONIZATION (RACE CONDITION SOLUTION) ........................................................................................... 34
4.4. JAVA MEMORY MODEL (JMM) .................................................................................................................. 36
4.5. VOLATILE VARIABLES ................................................................................................................................. 39
4.6. ATOMIC VARIABLES................................................................................................................................... 41

5. FUNCTIONAL-STYLE PROGRAMMING (LAMBDAS STREAMS) .................................................................. 41

5.1. LAMBDAS ................................................................................................................................................ 41


5.1.1. Capturing Variables from Lambdas ............................................................................................ 43
5.1.2. Static functional interfaces in java 8 ........................................................................................... 43
5.2. METHOD REFERENCES ............................................................................................................................... 44
5.3. STREAMS ................................................................................................................................................ 46
5.3.1. Stream Operations ...................................................................................................................... 47
5.3.2. Slicing operations ........................................................................................................................ 49
5.3.3. Matching Operations .................................................................................................................. 50
5.3.4. Finding Operations (Optional Class)............................................................................................ 51
5.3.5. Reduction Operations ................................................................................................................. 52
5.3.5.1. Reduce method ...................................................................................................................................... 52
5.3.5.2. Collect method ....................................................................................................................................... 55

6. DATE TIME API ....................................................................................................................................... 57


6.1. DATE AND CALENDAR CLASSES .................................................................................................................... 57
6.2. NEW DATE TIME API (JAVA 8).................................................................................................................... 57

7. JVM INTERNALS ..................................................................................................................................... 59

7.1. LIFETIME OF A TYPE................................................................................................................................... 59


7.1.1. Loading ....................................................................................................................................... 60
7.1.2. Linking ......................................................................................................................................... 62
7.2. REFLECTION ............................................................................................................................................. 63
7.3. RUNTIME DATA AREAS .............................................................................................................................. 65
7.4. GARBAGE COLLECTION .............................................................................................................................. 67
7.5. STACK .................................................................................................................................................... 69
1. Generics
❖ It was introduced in java 5
❖ We know polymorphism promotes generalization for instance super classes can be used
as polymorphic types for methods and constructors parameters and they can also be used
as return types for methods and that would allowed to pass subclass objects as arguments
and we can also returns subclass objects from methods
❖ Similarly interfaces provide even more generalization as they can be implemented by
classes coming from completely different class hierarchy

 One way to generalize it for there is by defining the type as Object class (the root
class and every other class extends from it)

 Solution for this problem is to use generics types seed in this chapter. And
this the same code using generics
1.1. Generic type / parametrized type
❖ Generic type is simply a class or an interface with type parameters define in the
declaration
❖ Here is the basic syntax of generic type:

✓ the class name is followed by something called type parameters which are coma
separated
✓ they are enclosed in less then and greater than symbols
❖ Within the class type parameters (refer also as formal type parameter) can be used as:
✓ Type for instance variables
✓ Type for parameters and local variables within methods or constructors
✓ Method return types
❖ An example for generic class:

❖ parameterized type is reference type in generics class is refer: for example


Store<String> is parameterized type for class Store<T>
 Parameterized type is the type instance for generic type
❖ Diamond notations (only works from java 7) is when we create instance for generics
type we can code like this new Store<>();
 in this case type is automatically referred based on the type specified on the left size

❖ Generic is compile time concept which means that generics does apply at runtime at
runtime there is not generics at all.
✓ Its means that a compiler basically uses feature called type Erasure and as name
call it’s erase a type so compiler going to remove type argument or type parameter
when write byte code (<String>, <T> for example) and replace all type parameter
in class definition with Object class. After compilation everything will be Object.
✓ A compiler would also insert explicit casting

❖ Naming conventions for type parameter:


✓ you should definitely use single, uppercase letters
✓ some conventions:
▪ E: is refer to element when you create new collection type class
▪ K: for key, V for value if you write map
▪ N: refer to number when generic type dealing with numbers
▪ T: refer to type if the generic type is non collections and is not about
numbers
▪ S, U, V: for 2nd , 3rd and 4th types if you have more than one parameter
❖ Sub typing of generics types:

❖ Multiple type parameters:

❖ Restrictions for generics:


✓ Type argument cannot be primitive type. If is, it would be compiler error

✓ Type parameter cannot be used in static context for instance it cannot be used in:
➢ Type for static variables
➢ Static methods
➢ Static initialize

1.2. Bounded Type Parameter


❖ We know that generic type give the client code the flexibility to instantiate them with any
type argument. So the power in the client
❖ But sometimes we might to put some restriction on the client code with regards to what
type argument they can use while instantiating the generic type
❖ To do that we can use bounded type parameter
❖ Bounded type parameter is simply a type parameter with one or more bounds
❖ Here is a syntax for bounded type parameter :

❖ Example for using bounded type parameter:

✓ In this case, type T should be List or one of their subtypes


❖ Type parameter can have more than one bound in practice you will mostly encounter
(rencontrerez) only single bounded parameters
❖ Bounded type parameter allow generic class to access methods defined by bounds

✓ This methods should be defined in bound itself, if this method is one of


specification of his subtypes, then compiler will get again compiler error
✓ In compiler, if generics have bounded type parameter, then their type parameter
will replace by his bounds (type erasure).
 This is the benefits of bounded type parameter
❖ Valid bounds:
✓ Class
✓ Interface
✓ Enum
✓ Parameterized type
❖ Invalid bounds:
✓ Primitive
✓ Array
❖ Specifics for bounded type parameter:
✓ If type parameter have multiple bounds, then type argument must be subtype of
all their specified bounds

✓ If class is one of the bounds, then it must be first otherwise we get compiler error
✓ If first bound is class, then remaining bounds must be interfaces.
➢ In other word you cannot have more than one class in list of bounds
➢ You can have more than one interface and only interfaces too
✓ If bound is final class or enum then the type argument will be the bound itself
that’s because final class does not have subclasses and enum is essentially final
class too
❖ Item 23: Don’t use row types in new codes
✓ We should be not using row types
✓ Row type is a generic type without type argument. Its generic type but we have
instantiating it without any type argument
✓ Example 1 for row type (list):

✓ Problem with using row type is we would have the same behavior as we had
before generics was introduced that is compile time type safety is lost and we
want may runtime exceptions due to type safety problems
✓ Realistic example: comparative shopping engine which for given item fetch the
price information from multiple partner sources and this would allow to user to by
the item from the source that offer the lows price

 Using row type is dangerous


✓ Why is row type supported?
➢ Is for the sake of interoperability with legacy code
✓ Exceptions for using row types: it should be used in
➢ Class literal

➢ Instance of operator

1.3. Unbounded Wildcard


❖ We know that generic types through its type parameter indicates that it can be instantiated
with an unknown type (with parameterized type )

❖ But parameterized type like generic type can also indicate that each type argument can be
an unknown type and that is done using wild card and here is an example

✓ Using “?” and it can be read as store of some type what this means is the method
go doesn’t know or doesn’t care whether you invoked with store of string or
double …
✓ Basically parameterized type is being gentrified here
✓ Also we can referenced to this wild card as unbounded wildcard
❖ Wild card can be used only as type argument so it cannot be used as type parameter
 For instance is you used as type parameter like in this example than it would be
ambiguous to which of this 2 type parameter that data type of variable a is referencing

❖ Common usage of wild card:


✓ Its commonly to used as part of type of method parameters like this example

✓ Is can be used in assignment statement. it’s not commonly to see them being used
in this way
❖ Why cannot use Store<Object> instead of Store<?>:
✓ Limitation of using Object class of type argument would be that you can only
assign an instance that also has object as type argument (this is property called
invariance)

✓ But with wildcard we can assign an instance of any type like store of string or...

❖ Compiler’s type safety restriction:

✓ Cannot invoke any methods of the parameterized type with those methods use the
type parameter of the class level in the method parameter
✓ The only way can invoke those methods passing null value as argument
✓ If try to do that you have compiler error

 This example generate compiler error because we cannot assume the type of
elements in list 2 class, when we use it, we use type parameter of class level

1.4. Invariance
❖ We know that promise of generics is type safety at compile time, invariance is a property
that also helps with this
❖ Let’s consider hierarchy where book is subtype of bookmark, with invariance we have
this that is list of book is not subtype of list of bookmark

 That is means is you cannot assign an instance of store of book to a store of


bookmark and this is to ensuring compile time type safety
 If you not respect invariance property of generics type, you have compile exception
❖ For the same type argument inheritance of generics type is allowed

 If type argument is bookmark, then an array list of bookmark can be assigned to a


list of bookmark
❖ Arrays are something called covariant that means is if book is subtype of bookmark, then
book array is subtype of bookmark array and because of that we can assign book array to
a bookmark array

 But if you assign other subtype of bookmark in array of book, you have array
store exception like this example

 Difference between array and generics is generics insure type safety at compile
time itself while array insure that at runtime
❖ Item 25: Prefer lists to arrays
✓ If you feel type safety needs to be ensure at compile time then you should go with
list
✓ Arrays are important and have their place but it has type safety at runtime and we
know type safety at compile time is recommended.

1.5. Generic Methods


❖ Its especially useful for implementing static utility methods which are very reusable
❖ Item 26: Favor generic types
✓ Generic types are appropriate for container type classes like in collections API
which can store any kind of element that is classes are very generic
✓ It helps us write safer code to compile time type safety the benefit that it gives
✓ If you hence happen to write generic classes then you should try to main them to
generic types
✓ Like generic types, generic method are very generic too
✓ Generic methods also have their own type parameters and client get benefits of
using different type arguments
✓ Such static methods need generic then it need to be made generic methods
❖ Generic methods are method of constructors can introduce their own type parameter
❖ Syntax for generic methods:

✓ Type parameters defined in first (T1,T2) they can be used for:


➢ type of method argument
➢ local variables in corps of method
➢ method return type
✓ type parameters should be between methods modifiers and the return type
✓ Example: from java.uril.collection interface

✓ When method type parameter has the same name of class type parameter then,
method type parameter override the class type parameter when the method is
invoked. Like this example

✓ We can use method type parameter and class type parameter when they not have
same name like this example

 If this method is static method, we have compilation error, because class level
type parameter cannot be used in static context it can only be used with
instances
✓ We can use bounded type parameter in method type parameter

✓ We can use class level parameter like bound in method level parameter when
method type parameter should be extended the class level parameter

✓ When can use as bound method type parameter but it should declared first like
this:

❖ Generic methods or even generic constructors can exist with or not the enclosing type is
generic
❖ Generic method invocation: type argument inference
✓ It can invoke just like regular non generic methods
✓ Only additional thing is specifying the type argument as we are dealing with
generics here
✓ Type argument can be either automatically inferred by the compiler or they can
also be explicitly specified in the method invocation statement
✓ Step1: let’s consider generic method like this
✓ Step 2 (automatically): when we pass double for example to this method the
compiler will consider automatically type argument like double (if type passed is
primitive, the type argument would be the box primitive type)

➢ If method type argument are used in returned type only (not in


parameters), the compiler enforce the type argument from the calling
context

➢ If return type and both parameters use method type parameter, and if in
method invocation statement (first argument is string, second array list) in
this case type inferred will be the most specific common supper type
among the 2 arguments

➢ If parameters and return type used method type argument, and in


invocation type parameter different to return type than we have
compilation error.

 When we invoke generic method, compiler go first to type of parameters and


enforce them, if it not exist then it go to return type.
✓ Step 2 (explicit type argument): we can explicitly specify type argument by
passing type between ‘<’ and ‘>’ before method name and after ‘.’ operator in
invocation like this example

➢ If you invoke method in the same class when you declared, you should use
this reference like this example

➢ If you are invoke generic method from super class you should use super
keyword
➢ Explicitly invoking generic method s rarely used. There are some cases
when you should use explicit invocation for example when type parameter
not present in method parameter or in returned type. In this case you
should use it

1.6. Bounded Wildcards


1.6.1. Motivation
❖ Invariance property helps us with type safety at compile time but it’s also restrictive is
certain harmless scenarios where type safety is not concern
✓ For example we may have method called display that take list of bookmarks and
simply display them.
✓ The method is not going to add anything to the list
✓ So you can pass list of book.
✓ That is type safety is not concern and so method is completely harmless

❖ With generics, kind of method overloading cannot works because at runtime, generics
type would removed

❖ To solve this problem we have 2 solutions:


✓ Upper bounded wildcard: basically wildcard extends bookmark and with this we
can display method with list of bookmark or any subtype of bookmark

✓ Generic method with bounded type parameter: use generic method with bounded
type parameter

❖ You can use also lower bounded wildcard to allow all super classes of specified class to
be passes as type parameter in generic classes/methods by using super keyword

1.6.2. Upper bounded wildcards


❖ Upper bounded wildcard is can be read as list of some subtype

❖ Syntax: by using unbounded wildcard followed by extends


❖ It helps us to work on the inflexibility of invariants
❖ Unbounded wild card simply implies that object is the bound

❖ Upper bounded wildcard has the same compiler type safety restrictions as an unbounded
wildcard that is:
✓ We cannot invoke methods that use class level type parameter with any argument
except null
✓ This means that you can only do stuff by passing input parameter x as producer of
data but does not consume data

1.6.3. Lower bounded wildcard


❖ If you want to consume data then we need to go with lower bounded wildcard
❖ Lower bounded wildcard can read it as list of some super type
❖ You can use lower bounded wildcard to allow all super classes of specified class to be
passes as type parameter in generic classes/methods by using super keyword

❖ Syntax: by using unbounded wildcard followed by super

❖ Lower bounded wild card is act as consumer of data and in the same time ensures that
compile time type safety is not compromised
✓ Can invoke methods that use class level type parameter only if argument is of
lower bounded type or one of its subtypes
✓ Example:

❖ Lower bound is only for wildcards cannot use it with type parameter

❖ Wild card ‘?’ can have only single upper or single lower bound (not like generic type
parameter they can multiple bounds)

❖ Item 28: Use bounded wildcards to increase API flexibility


✓ If you writing API’s then you would want to see if bounded wildcard can be used for
method parameters
✓ From design standpoint, it would be great to use them whenever possible
✓ Note 1: If the input parameterized type produces data then you should use upper
bounded wildcard
✓ Note 2: If input parameterized type consumes data then use lower bounded wildcard
✓ Note 3: if input parameterized type produces data and you don’t know or don’t care
what type argument is in the invoking code then use unbounded wildcard.
✓ Note 4: if parameterized type access both producer and consumer then you need to use
an exact match.
❖ When using wildcard or generic methods:
✓ Use generic method if :
➢ the same type parameter appears multiple times in the method declaration
➢ but its dependencies exist among type of 1 or more method parameters
and/or return type
➢ for example:

✓ otherwise, use only wildcards (non generic methods)

1.7. Generics Restrictions


❖ Type argument cannot be primitive. In this example would give compiler error

❖ Class level type parameter cannot be used in static context. For instance it cannot be used
as type for static variables/static methods/ static Initializers
 If static method needed generics then use generic methods
❖ We cannot overloading methods that will have the same signature after type erasure

❖ Generics and arrays do not mix them. For instance you cannot
✓ create an array of parameterized type

✓ create array of type parameter

 all them gives creation error at compile time


❖ we cannot have generic exception and error types that is we cannot have generic types
that are direct or indirect subtypes of the class throwable
2. Nested Classes
❖ Java permits nested classes that is classes defined within other classes
❖ Nested classes definitely have certain place and some of the collection framework classes
use them quite extensity
❖ We can have nested class or nested interfaces and in practice is recommended to develop
nested classes at the end of class like this:

❖ Example of nested class:

❖ To understand need for nested classes let’s consider hash map.


✓ We know that in hash map each key value pair is call as mapping
✓ If you recall in hash map implementation mapping is refer to Entry
✓ Entry is actually nested interface within the map interface
✓ If we invoke entry set method on hash map instance it would return set of all
mappings (set of all entries) and each entry is implementation of entry interface
✓ This set is nested class called Entry Set which implement set interface
✓ If we invoke iterator method of returned set then it return implementation of
iterator and this implementation is another nested class in hash map called Entry
Iterator
✓ If we invoke next method on the entry iterator it would return an Entry instance
which is next entry in hash map and this entry instance represented by nested
class called Node
 Why cannot we have all these nested classes as separate top level classes within
same package as hash map?
✓ If you do that, you will have 8 additional classes in the package and all 8 are
used only by hash map. So it would to class pollution
✓ Also have in these classes define as part of hash map tells clearly that these
classes have something to do with only hash map. So functionality kept closer to
the original class
✓ It also need to better design. you can see that within hash map these nested
classes are modularize the functionality
 Nested class basically serves its enclosing class and better design too
❖ Different types of nested classes:
✓ Inner classes: can access the instance members of the enclosing class
➢ Non static member classes
➢ Anonymous classes (except cannot access instance members if it is in
static context)
➢ Local classes: very rarely used (except cannot access instance members if
it is in static context)
✓ Static members classes: can never access the instance members of the enclosing
class
❖ Visibility:
✓ Nested classes: can be declared with all the 4 access levels (private default
protected and public)
✓ Top level classes: can only be public or default
❖ There is mutable accessibility of members including private members:
✓ Nested class can access any member of outer class
✓ Similarly an outer class can also access any member of the nested class because if
nested was not there then al that functionality would have be part of the outer
class
❖ Compilation:
✓ When have class nested with another class then java compiler will produce 2 class
files one for outer class and the other would be for nested class

✓ In case of anonymous classes outer would still be outer. class and anonymous
would be outer$1.class
2.1. Non static Member Classes
❖ Non static member classes is used when the inner class object needs access to the
enclosing object so that it can access instance members So it has something to do with the
instance class
❖ It cannot be created unless the enclosing object is already created. So enclosing object is
created first then it is used to create the inner class object
❖ It’s simply an instance member of the enclosed object just like any instance member.
❖ So we can access to this class using <outer class name>.<inner class name> like this:

❖ Inner class object would maintain hidden reference to enclosing object and building such
hidden reference take subspace time
❖ Outer class object will not be garbage collected until inner class object is alive
❖ Common use of non static member class:
✓ To define an adapter. It used to produce different views of outer class object. For
example the collection views methods in map interface

❖ Syntax :
✓ Create new non static class:

✓ Create instance of non static class: there are 2 way to access create non static
member class:
➢ 1st way:
▪ A special form of the new operator is used to instantiate a non-
static member class:

▪ Example:

➢ 2nd way:
▪ Create method to create new instance for non static member class
like this:
❖ Non static member class cannot have static members. If you do that you have compiler
error. the reason for this is static members should be accessible without an object but we
know that to create inner class object we first need to create outer class object

❖ Access:
✓ From the enclosing class we can access the inner classes method using the inner
object reference
✓ How inner class can access outer member: Here go method is accessed from inner
class:
➢ If go is not exist in the inner class then it will invoke the go method in the
outer class

➢ This in inner class always reference to inner class members: for example if
go in outer class only and we invoke this.go() then we have compiler error

➢ If you want to explicitly access method from outer class then we can use
<enclosing class name>.this.<method name> (use that if inner and outer
have same name method)

2.2. Anonymous Classes


❖ It’s basically anonymous that is it does not have name
❖ To understand anonymous class let’s consider:
✓ Tree set constructor which takes comparator as input
✓ We should create implementation comparator interface.
✓ However we can use anonymous class to implement comparator interface.
✓ Here how it’s done: the argument to the tree set constructor is an instance of an
anonymous class that is implementing comparator interface

❖ With anonymous class, we are both declaring and instantiating at the point of use and we
can to anywhere but usually it used as method argument
❖ Any local variables access from the enclosing method should be final. However from
JDK 8, it is possible to access the non-final local variable of enclosing block in local
inner class.
 Note that in order to be able to use local variables, they must be effectively final
that’s means we cannot change value of local variable in nested class
❖ Common use of anonymous class:
✓ Is for creating function objects: the comparator implementation we just sow was
an example for function object
✓ Function object has 2 property associated with it:
➢ Its methods operate on other objects: that is method parameters are other
objects
➢ It export only one method
✓ If anonymous interface is interface so we refer to it as functional interface
✓ Functional interface however it does have more than one method (it has one
abstract method)
❖ Item 21: use function objects to represent strategies as in strategy pattern
✓ For example compare method has defined strategy of comparing via length of
input strings
✓ We can use other anonymous classes to define other strategies
❖ Syntax: to create anonymous class we can just extend existing class or implement
existing interface only
✓ Extends class:
➢ When we instantiate an anonymous class from an existent one, we use the
following syntax:

➢ Example:

 Naturally, if the parent class constructor accepts no arguments, we should leave


the parentheses empty.
✓ Implement interface:
➢ We may instantiate an anonymous class from an interface as well:

➢ Example:

❖ Best practice for anonymous classes:


✓ It’s definition should be short: 10 lines or fewer otherwise it will affect readability
(item 22)
✓ If anonymous class object would be executed frequently, then we are also
repetitively creating anonymous objects and that could be very expansive.
 In such cases we can use private static final field to declare and instantiate
anonymous class as we see here:

❖ Anonymous class can have access to the enclosing class if and only if the anonymous
class in non static context. Static context means
✓ It declared inside static method
❖ It cannot have named constructor. But it can use instance initialize to initialize any
variables
❖ Anonymous classes cannot have any static members except for those that are constant.
❖ Limitations:
✓ Cannot inherit from multiple types that we cannot implement multiple interfaces
or extend class and implement interface at same time
✓ Client use anonymous object can only invoke members that are inherited from it
super type that is impossible to invoke any members that are defined only in
anonymous class
✓ It can be instantiated only at the point of the declaration
✓ It cannot be used with instance of tests or anywhere class name is required

2.3. Local Classes


❖ Local classes are classes that are defined within method so they just like local variables.
✓ They are part of method they can only be instantiated somewhere within method
✓ They can also have multiple constructors
✓ They can inherit from multiple types just like any other class
✓ Local classes are part of methods they also have to be short otherwise they would
affect readability.
❖ Any local variables access from the enclosing method should be final that is they should
be declared with final modifier. However from JDK 8, it is possible to access the non-
final local variable of enclosing block in local inner class.
 Note that in order to be able to use local variables, they must be effectively final that’s
means we cannot change value of local variable in nested class
 You would define it within method because defining them outside method doesn’t make
sense
❖ Local classes are rarely used
❖ Rules of Local Class:
✓ The scope of local inner class is restricted to the block they are defined in.
✓ Local inner class cannot be instantiated from outside the block where it is created in.
✓ A local class has access to the members of its enclosing class.
❖ Syntax: A local inner class can be declared within a block. This block can be either a
method body, initialization block, for loop or even an if statement
❖ Accessing Members: A local inner class has access to fields of the class enclosing it as
well as the fields of the block that it is defined within. These classes, however, can access
the variables or parameters of the block that encloses it only if they are declared as final
or are effectively final. A variable whose value is not changed once initialized is called as
effectively final variable. A local inner class defined inside a method body, have access
to its parameters.

2.4. Static Member Classes


❖ Syntactically, it is similarly to non static member classes only difference would be
addition of the modifier static in the class declaration.
❖ However they both are very different from each other
❖ Item 22: Favor static member classes over non static
✓ It just that when non static member classes are not required they need to prefer
static member classes
 Reason related to performance: if you don’t need to access to members of
enclosing class object then you should go with static member classes.
 That would mean we don’t have to build hidden reference to the enclosing object
which obviously save time and space
❖ Static member class is simply static member of the enclosing class and it means that:
✓ Can be accessed without having an instance of the enclosing class like static field
/ method.
✓ For instance here static field in static member how can be accessed

✓ Here how can create instance of static nested class:

✓ From within static member class, we can only access static members of enclosing
class
❖ Static member class is just an ordinary class but declared inside another class
✓ Can include static and instance members
✓ It can make as non instantiable by using private constructor
❖ Common uses:
✓ To represent private component of enclosing object: like Node class in hash map
✓ Represent strategies
✓ Public helper class

2.5. Variable Scope with Nested Classes


❖ Local variables cannot be shadowed and there is an exception to that statement
❖ Local variables can shadowed by variables in nested class which can be anonymous class
or local class as both of these class can be declared within method
❖ However local variables cannot be accessed from within nested class
❖ Local variables from the point of declaration to the end of its block. So it cannot be
shadowed in its block

❖ But with nested classes, we can shadow local variables like this example

3. Enums
❖ Lets consider class Gender which is constant exporting class and its defining 2 groups of
constants

 This kind of pattern that exports only in constants is refer to as int enum pattern
 Before java 5, its standard pattern for exporting constants
 But it has several deficiencies
✓ Lake of type safety: for instance
▪ Let’s consider this class itself
▪ Let’s say that there is also method which is expecting one field as
input
▪ But client by mistake might pass other field as input
 So type safety is lost and it may result some serious error
✓ Code is brittle: these constants are compile time constants So wherever
they are used in client code their values get copied but if any of these
values get changed here then they will not be reflected in client code
unless client code is recompiled
✓ There is no namespace protection: If you want to print name of particular
constant then that would not easy to do
✓ If want to iterate over constants of particular group then it may not be easy
possible
➔ To resolve this problems java designers have better design like this example:

 The only problem with this design is that writing such constant exporting class is
cumbersome. Its looks complicated
❖ So language designers wanted to make it simpler. so in java 5, they come with enums
which have simpler representation
❖ So we can represent our example in this way which is much readable

 But after compilation, this enum would be translated into regular class. Into byte code
we just have this

 Example for using previous enumeration:

❖ Enum is essentially class that defines fixed set of constants


❖ Enum Constants are
✓ Full blown objects.
✓ they are static and final
✓ They have same naming conventions as regular constants
✓ They also refer to as elements of the type, members of the type or enumerators of
type
❖ JVM loads enums when it’s used for the very first time (on first use)
❖ Item 30: Use enums instead of int constants
3.1. Enum Class
❖ We learn that every enum is essentially a class which extends the class java.lang.Enum
❖ In implement 2 interfaces: comparable and serializable
❖ It has constructor which takes name and ordinal
❖ It has compare To method which compare 2 enumerations
❖ It has many others methods you can see java API to more learn about it

3.2. Enums with State Behavior


❖ The enum is very basic and it just exports few constants
❖ But sometimes it can starts life directly as simple collection of constants and then it may
evolve over time
❖ In addition to constants enum can have
✓ instance variables for representing state
✓ methods to represents behavior
✓ private constructor in order to associate behavior with enum constants
▪ cannot have public or protected access modifiers (because it non insatiable
and cannot be extended)
▪ if access modifier is not present then by default it would be private
❖ example for state and behavior in enum class:

✓ in this class, each genre constant have its own value (own age)
✓ for that reason we have constructor for initializing the variable
✓ and each enum constant passes the corresponding value for initializing the
variable (value passes entre parentheses when define constants
✓ It has method for return value of state (in this case for value of age to read).
▪ If we invoke this method enum constant it would return the value of the
state
 The enum constants must be the first things to be defined in the enum
❖ Enums can define static members explicitly (static states and behaviors).

3.3. Nested enums


❖ Enum can also be nested within class or an interface
❖ If an enum is generally useful you can make it top level one
❖ but if you things that is has in some context thing it make since then it can be nested
❖ example for nested enum :

✓ implicitly nested enum would be static nested class because basically it is


static final class after compilation
✓ it cannot be inner class because inner class cannot have static members well
and enum have static members
✓ enum class cannot access instance members from the enclosing class
✓ after compilation it would produced 2 classes:

✓ to access nested enum constant like HORROR in our example you would do
Book.BookGenre.HORROR
(<enclosing class name>.<nested enum class>.<constant>)
❖ Difference between static member class and nested enum:
✓ Static member class is instantiable
✓ Nested enum is not instantiable
❖ An enum can be nested with within another enum and that enclosing enum can be nested
enum too or top level enum too
❖ Static member class can also have nested enum
 Inner class cannot have nested enum as nested enums are implicitly static

3.4. Enums with Constant-specific Behavior


❖ In this part, we would associating behavior that is specific to each enum constant
❖ It can be done in 2 ways:
✓ Switch statement

 Limitation: the limitation with using this way is if we add new enum constant
then we may also have remember to add case block in switch statement
✓ Constant specific methods:

▪ It’s interesting as you can see that each constant is associated with body
▪ This body is refer to as constant specific class body
▪ Specific class body can have
o variables
o methods (are referred to as constant specific method
implementations)
▪ To force developer to add constant specific class body to each constant,
we can add abstract method to enum class
▪ Any variable declare in the enum and it is access within constant specific
body should have access level at least default (not private)
 For each constant specific class body definition, the compiler creates an anonymous
class that extends the enum type
 If we have enum constants with constants specific class body then the enum type will
no longer be final
4. Concurrency (Multi-threading)
❖ Multithreading is nothing but performing multiple activities at the same time
❖ Many examples for usage of multithreading :
✓ In Smartphone applications updating in background
✓ Web browser where we see the pages and within this pages we have regular
content and images and images keep getting downloading concurrently when
network is very slow
✓ Web sites displaying advertisements
✓ Web crawlers which search engines like Google use
✓ Federated search is an information retrieval technology that allows the
simultaneous search of multiple searchable resources.[citation needed] A user
makes a single query request which is distributed to the search engines, databases
or other query engines participating in the federation. The federated search then
aggregates the results that are received from the search engines for presentation to
the user. Federated search can be used to integrate disparate information resources
within a single large organization ("enterprise") or for the entire web.
❖ Motivation to see why multithreading is needed in the first place:
✓ We know sequential programming where the program is executed one step at time
and most problems can be solved using just sequential programming
✓ However certain tasks like read operations, input output my block until detail
available
✓ Blocking halts other tasks thus wasting CPU time
 The solution is concurrent programming which allow you to continue execution
even if task is blocked

4.1. Threads
4.1.1. Introduction
❖ We know when operating system run single program which used all the expensive scare
system resources and that was very inefficient
❖ Operating system then evolve to allow multiple processes to run concurrently
 the process is nothing but a running program that is a program instance
❖ each process gets its own resources such is memory file handles … just like the way our
JVM gets its own memory from the underling operating system
❖ an concurrency is achieved through multitasking which is nothing but simply switching
the CPO from one process to another process
 multitasking does not imply parallelism a CPO is being switch from one to
another that is at any given instance of time CPO still executing instructions from
single process
❖ however switching having so fast that it give some us an illusion of parallelism which is
possible only on multi process system

4.1.2. Threads
❖ Thread is essentially a single sequential flow of control within process that is statement
within thread are executed sequentially
❖ An thread is part of process and each thread is basically light weight process
❖ An process can have multiple threads
❖ Those threads share the resources that process allocated like the memory and file handles
but each thread has its own PC own stack and local variables.
❖ Threads benefits:
✓ Exploiting multiple processors: that is the threads you creates can run on multiple
processors thus achieving parallelism
✓ Allow loosely couple designs
✓ Better throughput even in single CPU machines when blocking tasks are involved
❖ Threads types: there are 2 types of threads
✓ Daemon thread: is background thread useful for tasks such as garbage collection
✓ Non daemon thread:
▪ Creates within the application that is these are the threads which are
programs create
▪ Main thread: when start our program JVM also creates thread to run the
main method
▪ JVM will not terminate if there is at least one non daemon thread which is
running
❖ Threads analogy:

❖ In java thread is simply an instance of class called java.lang.Thread or one of it


subclasses.
❖ A task that is the work is defined by class which would implement the interface
java.lang.Runnable
❖ Launch thread:
✓ Step 1: Create task: simply we need to create Runnable object

▪ Runnable has exactly one method called run()


 MyRunnable is class which implement Runnable interface
 MyRunnable class would define the task within the run method which it
implements
✓ Step 2: Create thread with Task: simply instantiate Thread class and initialize it
with the task that we created

✓ Step 3: Start the thread: simply invoke the start method on the thread instance

 For this new call stack will be created for this thread and the run method and the
run method will be pushed on this stack
❖ Thread Scheduler:
✓ which is responsible for moving the thread from runnable state to running state
✓ once the thread is in running state its call stack would be active and the method on
the top of the stack will be executed
✓ If it’s the run method then run method would be executed.
✓ So it’s the component doing the switching between the threads
✓ There are other state called blocked and there are few reasons why thread can get
to this state and one of them as you is due to blocking during input output
operation like read
✓ Thread can get to block state from only running state and from block state to
runnable state
 Thread scheduler makes all decisions about who runs who doesn’t run and
how long they’re run
 There is no guarantee on how thread scheduler behaviors
❖ There are many ways to launch thread:
✓ 1st way: Create separate class implement Runnable interface

✓ 2nd way: Thread class itself implement Runnable interface we can do that
 Its prefer to use 1st approach because from good object oriented design standpoint if
there are different activities then will be represented by different classes (loosely
couple) and Task/Thread are 2 different activities
❖ To put the thread sleep you can use this method from Thread class like this:

 Its static method in the thread class


❖ Thread group is basically something with is related to security and also related to
appliqués. So it’s basically obsolete. You can logically group some threads on perform
some activities on them as group
 To do that there are thread pull executors
❖ Thread class methods:
✓ Current thread method:

▪ by this static method thread can get access to its own object (to current
thread object)
▪ its static method from Thread class
▪ with that will give reference to the current thread
▪ output of this method is:

✓ set name method:

▪ its instance method


▪ you can pass name of you own thread by this method
▪ We set names for many reasons. This is example of usage:
o For example there are many web sites which we want to crawl but
we only can create hundred threads (our system has certain
limitations).
o If we want to know which web sites are being called at particular
instant of time so we can set name and print name of all web sites
that are being crawl
✓ Set priority method:

▪ Its instance method


▪ We can pass priority of thread
▪ By this method you are trying to influence the scheduler
▪ we are saying that between 2 threads try to give more priority to thread
1(max priority) which means that bring to running state before you’ll bring
thread 2(min priority
✓ yield method:
▪ it’s static native method
▪ it’s nothing but hint to scheduler that this particular thread is willing to
yield is current use of CPU
▪ its try to influence the thread scheduler
✓ join method:

▪ here we are saying that main thread suspended until t2 complete its
execution
▪ which mean the executor thread (thread who launch t2 thread) suspended
until invoker thread (t2) complete its execution
▪ Waits for this thread to die.

4.2. Race Condition


❖ Concurrency helps in better resources utilization which in turn helps in improving
throughput
❖ The main complexity of concurrency programming comes when the same object is shared
across multiple threads and that object has some state data which can be modified by
threads
❖ Example:

✓ Let’s consider 2 users ‘John’ and ‘Anita’ and they are married coupe.
✓ They have join bank account and they have balance of only hundred dollars
✓ 2 users are presented by threads and there is task called bank account
✓ Bank account has instance variable called balance and one instance method called
make with dollars which is invoke when user is making with dollars
✓ Implementation of making with dollars method:

✓ When users access banking application then bank account object will be created
for that users account and will passed as input the thread that represent this user
✓ If john and Anita happened to join application in the same time then since they
represent the same account only single bank account object will be created for
them and will be passed as input to that 2 threads
 Problem: Let’s consider that john and Anita want to withdraw 75 dollars at the same
time

 Bank account object was not thread safe because bank account has state that is the
instance variable balance is mutable
 Bank account object was been shared between threads which will access method that
can change the mutable state.
 The process of changing the state was not property managed due to bank account was
not thread safe.
 When we say properly managed means is they was particular concurrency has that
race condition
❖ The type of race condition is called as check then act which is very common type of race
condition
❖ It called check then act as they first making check if there is enough balance and only
then we are performing some action which is to compute the new balance
❖ the solution is that make with drawal method should be made to run as one single atomic
unit that is once the first thread allow to finish before any other thread can invoke this
method.
 This behavior is refer to as mutual exclusion: only once thread can enter the
method at once time
❖ Non thread safe object means an incorrect program which due to data corruption
❖ 2nd example for race condition:

4.3. Synchronization (race condition solution)


❖ For run method as single atomic unit, java building locking mechanism called
synchronization
❖ Synchronization is to protect critical data which is shared and also mutable like balance
instance variable
❖ Item 66: Synchronize access to shared mutable data
✓ Synchronization ensure data protection by this allowing threads from interfering
with each other
❖ Synchronized block:
✓ When we talk about synchronization, we talk about block of code which needs to
be synchronized. And this block of code can have one or more statements
✓ Synchronized block basically contains 2 parts
▪ Lock: it act like real lock. Its reference to an object
▪ Block of code: This needs to be guarded by this lock. It would be critical
data that needs to be protected
✓ Syntax:

✓ Example:

✓ Locking: keep in mind that


▪ Every object has single lock
▪ Every thread interring synchronized block will automatically acquire
the lock
▪ Every thread will release it either it exciting synchronized block or in
an exception is generated within synchronized block
▪ At most one thread can acquire the object’s lock
▪ If thread wants to enter synchronized block but lock is unavailable then
the thread goes into BLOCKED state.
 It will wait for lock to released by current thread and once lock is available it
would acquired and enter synchronized block
 If many thread wait for lock to be released, so thread scheduler will decide
who that lucky thread is after lock is available
 Its intrinsic or monitor locks
❖ Synchronized method:
✓ It’s simply shorthand for synchronized block
✓ We simply use keyword synchronized in the method declaration
✓ With that the entire method is guarded by lock
✓ Here the lock is simply the object on which the method is invoked
❖ Locks and synchronized methods:
✓ Locks are per objects and not per methods
 It means if one thread has acquired an object lock then no other thread can
enter any of the object’s synchronized method
✓ Thread can enter any unsynchronized methods of the object even if lock is already
acquired by some other thread
✓ Static synchronized methods use class object as the lock. So every class has single
lock and every object also has single lock
❖ Coordinating access to shared variables:
✓ Need to use synchronization everywhere the variable is used

 Synchronization means not only just mutual exclusion but also reliable
communication between threads
✓ Always use the same lock when guarding the same shared mutable variable.
Because when use different locks you can lost concurrency system between
thread.

4.4. Java Memory Model (JMM)


❖ In multiple scenarios in multithreading environment, we have seen things can work in an
unpredictable (‫ )ال يمكن التنبؤ به‬way as it’s a structured which managed every thing
❖ Java memory model which defined such ordering. It’s part of java language specification
and it related to multithreading which using shared mutable data
❖ It’s used especially when we are dealing with shared mutable data.
❖ It’s just bench of rules which we need to be aware of
❖ We are working in this part with this example when we have 2 threads share mutable data

✓ Out of order actions:


➢ For instance john’s thread is inside make with drawal method and does the
balance check and go to RUNNABLE before updating balance
➢ Anita threads come be active in RUNNING state and access balance
variable which is not updated
✓ Multi processor with shared memory:
 There is lack of thread coordination and needed to performance
✓ Most of the time threads deal with only their own stuff and it’s not required to
communicate with other threads
✓ Communicating with other threads on every write operation can be expensive and
could be really bad in multiprocessor system with share memory due to the need
for frequent update that need to happened between the local cache and the
memory
✓ Thread coordination is required only when mutable state shared across the threads
like in own example
✓ If there is shared state that is mutable then it’s program responsibility not JVM’s
to ensure that threads coordinate
 Coordination access to shared variable:
✓ Synchronize everywhere variable is accessed

 When john’s thread access make with drawal method then Anita’s thread
cannot access get balance until john’s thread terminate their process
✓ The happens before relationship is achieved through synchronization and this
notion of happens before is part of java’s memory model and JVM implement
java memory model
✓ When we see synchronized keyword than it known that there is need for inter
thread coordination and for this it insert special instruction called memory
barriers which would install the underlying architecture to any necessary
memory coordination between the cache and the shared memory

❖ Happens-before defines a partial ordering on all actions within the program. To guarantee
that the thread executing action Y can see the results of action X (whether or not X and Y
occur in different threads), there must be a happens-before relationship between X and Y.
In the absence of a happens-before ordering between two operations, the JVM is free to
reorder them as it wants
 Happens before ordering (rules): Happens-before relationship is a guarantee that
action performed by one thread is visible to another action in different thread.
✓ Single thread rule: Each action in a single thread happens-before every action
in that thread that comes later in the program order.

✓ Monitor lock rule: releasing lock happens before every subsequent acquisition
of that same lock (in own example of make with drawal invoked first then
john’s thread execute method releases the lock which is then acquired by
Anita’s thread in order to get balance

✓ Volatile variable: volatile is keyword that can be used when declaring variable
and the A write to a volatile field happens-before every subsequent read of that
same field. Writes and reads of volatile fields have similar memory
consistency effects as entering and exiting monitors (synchronized block
around reads and writes), but without actually acquiring monitors/locks

✓ Start method: A call to Thread.start() on a thread happens-before every action


in the started thread. Say thread A spawns a new thread B by calling
threadA.start(). All actions performed in thread B's run method will see thread
A's calling threadA.start() method and before that (only in thread A) happened
before them.

✓ Join operation: All actions in a thread happen-before any other thread


successfully returns from a join on that thread. Say thread A spawns a new
thread B by calling threadA.start() then calls threadA.join(). Thread A will
wait at join() call until thread B's run method finishes. After join method
returns, all subsequent actions in thread A will see all actions performed in
thread B's run method happened before them.

✓ Interrupt operation: its method and can be invoked on thread to tell that thread
that is should stop what it’s doing and do something else. Generally it’s
invoked on thread as means to terminate the thread
✓ Object finalize operation: (it invoked by garbage collector when it detect that
there are no more references to the object.) The end of the constructor of an
object happens before the start of the finalize of that object
✓ Transitivity: if action A happens before action B and if action B happens
before action C then action A happens before Action C.

4.5. Volatile Variables


❖ It’s simply modifier that is used with variables and it helps ensure memory visibility that
is once particular thread write value to volatile variable it’s guaranteed that the particular
value would be visible to all subsequent greet of that variable from all threads
❖ It will be propagated to all other threads
❖ Its alternative way to assume memory visibility synchronization would also helping doing
that
❖ Volatile variable values are also stored in main memory so there are not caches or
registers or in local cache processors. That is any processor will always write volatile
variable value to main memory and will also read from only main memory
❖ Volatile keyword can be used
✓ With shared mutable variable
✓ Volatile keyword cannot be used with local variables as scope of local variables
ends with block in which they are defined
✓ D
 Example for using volatile keyword:

✓ Goal of this is to stop the threads: from the main thread we want to stop the
second thread
✓ There are 2 threads
• One is the main thread
• Other is shown in grey box where we are used anonymous class to
implement the task
✓ We use shared mutable variables declared as volatile and with default value false
✓ Second thread has loop and within loop we are printing some text until stop is set
to true
✓ After second main thread set stop to true so the thread would terminate
✓ If stop variable is not declared as volatile then there is not guarantee that the
second thread will ever get to see the updated value of stop and it may infinitely
loop
 Volatile keyword is establishing it happens before ordering and is allowing the 2
threads to coordinate effectively
 The same example but with synchronized keyword:

 When we use volatile we have memory visibility but we would still have the race
condition when 2 threads access one method at same time.
 Synchronization do both it do memory visibility and race condition.
 Basically locking that synchronization can guarantee but memory visibility and
mutual exclusion while volatile variable can only guaranty visibility
 Use volatile variable: If there is single thread that is writing to shared variable and
other threads read the value of that variable then there is no question of race
condition. Also when we have multi threads writing shared variable same value (like
stop example all threads set to true).
 Use synchronization: if there is race condition then we cannot use volatile and we
need to use synchronized also with synchronization we have benefit of memory
visibility.
❖ More on memory semantics:
✓ All actions that precede either write to volatile field or release of lock are visible
to all actions that follow a “subsequent” read of the same volatile variable or
acquisition of same lock.
✓ Let’s say we have thread A and within this thread we have some actions and those
actions either write to volatile field or release of lock
✓ And we have thread B which read from same volatile field or acquires same lock
that was released earlier
✓ With that all the earlier actions that we sow in the cloud will be visible to thread B
also
4.6. Atomic Variables

5. Functional-style Programming (Lambdas Streams)


❖ There is also an other programming paradigm calling functional programming
❖ Languages like Lisp is functional programming
❖ Functional programming is all about programming using functions that is methods is our
java terminology
❖ FP (functional programming) helps in writing compact code more back free code and
code that is easily parallelizable.
❖ Java designers realize this and they make this possible in java 8by introducing functional
programming constructs like lambda
❖ With java 8 you can pass functions as arguments methods and within those methods you
can use those functions.
❖ Functional programming constructs enable us to write:
✓ More compact and efficient code
✓ Such code can helps to very easily exploiting parallelism in multi-core system

5.1. Lambdas
❖ Lambda is essentially a function which can be passed around. It’s not associated with any
class and it’s simply a function by itself
❖ It enable in writing faster more compact and cleaner code
❖ Before lambda, anonymous class are used to perform similar tasks of passing around
functionality
❖ Lambda is exactly:
✓ Anonymous function
✓ Its compact way of defining function which can be passed around
✓ Useful when we want to passed some functionality and it helps in doing it in very
compact way
❖ Lambda expression syntax:

 There are many simplifications for this syntax:

➢ 1st simplifications: remove type of parameters as they can be automatically


inferred by the compiler

 The compiler infers the type by type argument that is also specified in
instance creation expression
➢ 2nd simplification: if body has single statement then we can have
something like this (braces, semi colon and ; can be omitted)

➔ The function is not expected to read anything


❖ Lambda expression is assigned to variable
✓ Whose type is functional interface (can be implementation for only functional
interfaces)
✓ Would be method parameter
 Functional interface is an interface whose expose single abstract method (refer also as
Single Abstract Method (SAM) interface)
❖ Lambda expression example:

❖ Anonymous class vs. lambda:


5.1.1. Capturing Variables from Lambdas
❖ From within lambda expressions, we would like to access variables from the enclose
scope in which lambda expression has been defined
❖ Scope variables in lambda expression (it’s like scope variables in nested class):
✓ Local variable defined in the enclose method: then the rule is that there is
constraint that the variable has to be effectively final which means that the value
should not change in all their block (lambda or enclosing method)
 With anonymous class if you use java 7 or before you should declare
variable like final but if you use java 8 it automatically declared as final
and you shouldn’t change their value
✓ Instance or static variable defined in the same class: then you can use it like any
other variable (it can be final or not).
❖ In lambda expression, you can use this keyword to refer to enclosing class

5.1.2. Static functional interfaces in java 8


❖ Functional interfaces define single abstract function
❖ Some functional interfaces before java 8 with semantics associated with them:
✓ Comparator and comparable: related to sorted
✓ Runnable and Callable: related to threads
❖ In java 8 several static functional interfaces where added
✓ are very generic function interfaces
✓ They not have any specific semantics associated with them.
✓ They already defined some structure
✓ These interfaces are part of this package “java.util.function”
❖ java 8 functional interface for java.util.function package:
✓ Predicate interface:
➢ which represent the Boolean expression for filtering
➢ definition this interface:

➢ it represent Boolean expression that uses object of type T


➢ it has few non abstract methods and default methods also
✓ Function interface:
➢ To perform transformation
➢ Definition of this interface:

➢ It takes an object of generic type T as input and returns an object of


generic type R
➢ This abstract method is applying some of transformation from T to R
✓ Unary interface:
➢ Sun interface of Function interface
➢ It’s also functional interface
✓ Consumer interface:
➢ Used for consuming something
➢ It has single method called accept and it:
▪ It takes parameter
▪ within the body we just consume the parameter
▪ Returns void
➢d
✓ Supplier interface:
➢ Used for supply something
➢ Its generic interface
➢ It has single method called get and it:
▪ Does not have any parameter
▪ It return something

❖ Functional interface annotation:

✓ If you are creating functional interface then you should also uses this annotation
✓ That way compiler ensure that this interface has only single abstract method
✓ That way if you want to add more than one abstract method you have compiler
error

5.2. Method References


❖ It’s very simple concept and it’s also used for passing around functionality just like in the
case of lambda expressions
❖ The target type for the method references are also functional interfaces just like lambda
and if not we have compilation errors
❖ It’s simply reference to method just like we have object references where we have
references to objects
❖ You can use method reference if you have that same logic encapsulated in method
❖ There are 3 types of method references in java:
✓ Reference to a static method:
➢ In this case, we have a lambda expression like the following:

➢ You can refer to static method defined in the class. Following is the syntax
and example which describe the process of referring static method in Java.
➢ Syntax

➢ Example

✓ reference to instance method of an object of a particular type:


➢ In this case, we have a lambda expression like the following:

➢ Where an instance of an object is passed, and one of its methods is


executed with some optional(s) parameter(s)
➢ Syntax:

➢ Example:

✓ Reference to an instance method of an existing object:


➢ In this case, we have a lambda expression like the following:

➢ Like static methods, you can refer instance methods also. In the following
example, we are describing the process of referring the instance method.
➢ Syntax

➢ Example
✓ Reference to a constructor:
➢ In this case, we have a lambda expression like the following:

➢ You can refer a constructor by using the new keyword. Here, we are
referring constructor with the help of functional interface
➢ Syntax

➢ Example

 Instead of using AN ANONYMOUS CLASS you can use A LAMBDA


EXPRESSION And if this just calls one method, you can use A METHOD
REFERENCE

5.3. Streams
❖ Stream is consider as one of the best use cases of
✓ Lambdas expressions
✓ Method references
✓ Standard functional interfaces
❖ It’s an API and its introduced as part of new package called “java.util.stream”
❖ Stream is an interface and it has many methods and many of its methods use standard
functional interfaces as method parameter types
❖ Its al about performing SQL operations on collections so we can perform some complex
operations on collections which were not possible earlier before java 8
❖ Problem: So we have database and we have SQL queries which helps us to manipulate
data in the databases and we perform all kinds of complex operations like:
✓ Filtering using where class
✓ Grouping data
✓ Sorting some data
✓ Summary operations like count, sum and average(avg)
❖ Before java 8:
✓ We can:
➢ Add something to collection
➢ Get something from collection
➢ Search

✓ But we cannot do any of this:
➢ Filtering
➢ Grouping
➢ Sorting (collection.sort external sorting)
➢ Sum and avg
✓ Limitations: To do these operations,
➢ Should get some custom code and writing such custom code is not
readable
➢ It’s not easily parallelizable
❖ To address that, java 8 has to introduce stream API and with that we can do all of these
operations
❖ Example:

 In java 8, it has introduced new method called stream in Collection interface which
return instance of stream interface and with that you can do any operation to such
collection
 If we replace stream method by parallel Stream, then the entire operations is
parallelized like this example so JVM would be able to leverage the different course
in the system and it will be able to parallelize the computation and make it much
more efficient

5.3.1. Stream Operations


❖ Stream pipeline:
✓ 1st step: set-up stream (tables in SQL word) by invoking stream/or parallel stream
method to collection interface or create instance of stream object
✓ 2nd step: invoke 0 or more intermediate operations (WHERE clause) lazy
operations and return Stream<T> (for example filter method or collect) .i.e.
transform a stream to another
✓ 3rd step: terminal operation (column name) eager/terminal operation and return
NON stream. Terminates (closes) a stream.
❖ Lazy operations:

✓ Streams are lazy because intermediate operations are not evaluated until terminal
operation is invoked
✓ Each intermediate operation creates a new stream, stores the provided
operation/function and return the new stream.
✓ The pipeline accumulates these newly created streams.
✓ The time when terminal operation is called, traversal of streams begins and the
associated function is performed one by one.
✓ Parallel streams don't evaluate streams 'one by one' (at terminal point). The
operations are rather performed simultaneously, depending on the available cores.
 JVM for each method is an eager operation so only when JVM is going to execute
for each method and at that instance it’s going to execute lazy methods
✓ Example lazy evaluation in sequential stream
✓ Example lazy evaluation in parallel stream

❖ Stream operations classifications:


✓ Filtering (intermediate operation): like filter operating it take predicate and
apply it on stream element
✓ Mapping (intermediate operation): like map operation it apply function on
stream element so it perform some kind of transformation
✓ Slicing (intermediate operation): its special type of filtering operations as they
also allow only certain elements of the stream to be processed. It does not take
predicate as input
✓ Matching and finding (terminal operation):
➢ match operations just check if stream elements match given predicate so
it return Boolean value it take predicate as input
➢ find operations are like search operations and hence they actually return
an element matching certain criteria
✓ Reduction (terminal operation): are used to reduce the stream elements into
single value it repetitively apply binary operation on the stream elements
✓ Collect (terminal operation): are used to produce an output like list or set or
map so input would be stream of elements but output would be something like list
or set or map

5.3.2. Slicing operations


❖ It is used to slice the stream. This way we are able to focus on only particular part of the
stream

❖ There are 3 operations for slicing stream:


✓ Distinct function:

➢ Used to return only distinct stream elements. If there are duplicated object
then this function will remove it
➢ it remove duplicate
➢ it used equal method and invoke it on each of stream elements
➢ stream element should have equal and hash methods
✓ limit function:
➢ it has input long and it return top parameter elements from stream
➢ it take size which should return as input
➢ after invoke this function, only n elements will be processed and rest of
elements will not be processed
✓ skip function:

➢ it’s the opposite of the limit function


➢ it’s just skip the fist n element which n is input parameter

5.3.3. Matching Operations


❖ It match (‫ )مطابقة‬stream elements to some criteria and after then Boolean value will be
return
❖ If certain condition is met then al of the rest stream elements that come after the condition
is met will not be processed (some for finding operation)
❖ There are 3 operations:
✓ Any match function

➢ It takes predicate and with predicate we are going to pass our criteria
➢ If there is at least one of the stream element is matching criteria in
predicate input
➢ As soon as stream element match this condition then it returns true
otherwise it return false
✓ All match function:

➢ It takes predicate like any match


➢ It all stream elements is matching criteria then it return true otherwise it
return false (if there is at least one not match criteria)
✓ None match function:

➢ It takes predicate (criteria) like any match


➢ If all stream element doesn’t matching criteria then it return true otherwise
it return false
5.3.4. Finding Operations (Optional Class)
❖ It used to find something in the input stream elements
❖ These operations would take some kind of search target like contains method and would
search again the input elements
❖ They don’t take any parameter but they typically are used with filter operations and they
can be used without
❖ There are 2 operations:
✓ Find any function:

➢ If there are stream of elements, so one of the elements would simply return
that element
➢ The returned element can be second third eight... Element. Its random and
the element returned can be any of them
➢ In non parallel setup typically it would usually return only the first
element but there is non guaranty
✓ Find first function:

➢ It return the first element from stream elements


➢ It would always return the first matching element itself
 If you are using parallel stream then if you don’t have the requirement to return the
first element then you should go with find any because if you are using parallel stream
and return first element then there is more work to be done
 With parallel stream the data stream element would be partition and different course
will be working with different partitions. Synchronization would be there

❖ Both of them return optional of element type. So optional is:

✓ it introduced in java 8
✓ is essentially container class which would have either matching element or it will
not have the element
✓ It saying that the value might be present or might not be present.
✓ It used to remove Null pointer exception when stream return null value.
✓ If you would check if optional class contain value use is Present method
✓ If you want to get value use get method

✓ You can use if present method if you have method to invoke if optional class have
value like this example:
✓ You can use or else method if you have to return default value

✓ You can use or else get method. It going to take different parameter take supplier.
Even if element was found then parameter function will not be invoked and it
invoked only if element was not found

✓ You can create optional instance of value using static method called of method
like this

5.3.5. Reduction Operations


❖ Reduction operations can be classified into 2 types:
✓ Collect methods:
➢ we collect stream of elements into list, set or map
➢ reduction that collect method does is refer to as mutable
reduction
➢ it’s mutable reduction because it produce in final mutable object
(object can change like string builder)
➢ Also it change value of object: first steps it takes empty container
and first element of stream and it mutates empty container and the
same container used to produce the final container
➢ The container should have mutable type
➢ reduce stream into container (list/set/map/string Builder/summary
object)
✓ Reduce methods:
➢ we reduce stream of elements into single value
➢ Reduce method does is mutable reduction. It would perform
mutable reduction
➢ if we use mutable reduction with this method they can have
incorrect result
➢ reduce stream into single value (max/min/sum)

5.3.5.1. Reduce method


❖ Reduce method is used to reduce stream of elements into single value for example:
✓ You have stream of number and you want to compute sum of elements
✓ Maximum or minimum
❖ Here is how the reduction happens that the reduce method works
❖ In reduction operation we have one method called reduce into 3 different syntax for this
method
 1st Syntaxe:

✓ If stream is empty then optional return don’t have any value


✓ The accumulator function will be invoked repetitively for stream elements
✓ Example:

✓ Imperative way:

✓ With parallelization:
➢ Syntax:

➢ How reduce method works in parallelization way (if we have 2 threads, 2


cores):

 For parallelization, reduction operation must be associative property in mathematics.


 If reduction operation does not support associatively then we can have incorrect
result and we can also have inconsistent result across multiple runs because order of
elements will be changed
 2nd syntaxe

✓ It takes 2 parameter for same types here


✓ It also taking binary operator like earlier syntax
✓ But the first parameter is can as identity
✓ It return value and not optional object
✓ Here if stream is empty then this particular method will return identity. It’s like
default value
✓ First element in stream with this method it takes identity and append to first
element

 If you have in some scenarios the parameters with some types then you should
use this version
✓ Example for using this syntax:

➢ Here we want to concatenate 3 strings called A,A and B in parallel setup


➢ Accumulator function it takes 2 objects of type T and produce object of
type T
➢ Reduce method will fist partition in 2 segments {A},{A,B}
➢ Each of threads will concatenate elements of 2 segments and it in first time
use identity
 3rd syntaxe
✓ We can use this syntax when we have an accumulator has like parameter 2
different types
✓ Syntax:

➢ Accumulator is bi function it takes 2 parameters with different types U and


T and produces U
➢ Combiner is binary function it takes 2 U like parameters and produce U
 If you have in some scenarios the parameters with different types then you
should use this version
 Whenever you are working with streams always test your output with parallel stream
in order to test for correctness because it might have true result with sequential stream
but with parallel stream incorrect result.
 It can have incorrect result because reduce method is doing mutable reduction. We
have container with mutable type and with parallel stream we have multiple
segments and for all segments (corps) will share the same container the same
container will be used for all segment so it will be coordination between threads
and container not thread safe.
 Reduction methods is used only for immutable reductions
 We use combiner function only if we are using parallel reduction because we need to
combine 2 result reductions on some object because in parallel stream you have 2
segments which produce 2 accumulated value and it will produce single result then
you need to combine them on the cumulative
 But it cannot be null in parallel or sequential streams.
✓ Example for using this syntax:

➢ Here we want to concatenate 3 strings A,A,B using string builder


➢ The problem here when we want to concatenate 2 elements from strings
we have 2 different type so we cannot use accumulator function (takes 2
parameters with same type)
➢ So we need another function called accumulator
➢ So we can called reduce function using this syntax like this:

5.3.5.2. Collect method


❖ It is used to collect stream of elements into container (container can be something like list
or set or map or any regular object
❖ Collect method are very important and also very interesting because
✓ It’s very common to collect stream of elements into something like list
✓ We can also group stream of elements into something like map or complex
grouping like within map value need not be single value it can also be another
data structure
❖ Collect method working:

✓ Accumulator function (a) is applied repetitively in different steps


➢ In first step it takes empty container and first element from stream and
then it mutates the empty container
➢ In second iteration the container with value 5 will be combined with the
second value from stream 1 …
✓ The same container is being used here and its being repetitively mutated with each
step of the accumulation
✓ We need supplier because we have to create this container the beginning of
accumulation process is the creation of the container and for the we use supplier
(its functional interface which can be used to create new object)
✓ The accumulator is another function which does the accumulation process
✓ Finally if we are dealing with parallel stream we also need combiner because we
have 2 containers for 2 segments and we need to combine them (each segment in
parallel stream will have his own containers) it combine accumulated containers
from each of the segments
❖ Syntax (there are 2 versions of this method) :
✓ 1st version:

➢ It takes 3 parameters
✓ 2 version:
nd

➢ It takes single parameter Collector


➢ R is type of container
➢ T is type of stream elements
➢ A is accumulator type
❖ Collect method examples (concatenate strings and produce string builder result):
✓ 1st version:

➢ it returns string builder


➢ it taking supplier accumulator and combiner
✓ 2 version:
nd

➢ it returns string
➢ it taking single parameter and it is called as collector
➢ Collector is an interface in util package
▪ Has certain methods which would return supplier accumulator and
combiner to perform mutable reduction
▪ Has couple of more methods
➢ Collectors class is essentially helper class and it’s helping in performing
some predefining reductions like to list, to set , joining …
➢ Joining is predefining reduction about concatenating strings
❖ Collector interface presentation:
✓ Is reduction operator and it helps in performing mutable accumulation if stream
into container
✓ It has many methods like:
➢ Supplier method: help in creating the container which we are suppose to
return. It return instance if supplier functional interface
➢ Accumulator method: accumulates stream elements into the container
➢ Combiner method: combine two result container which would the output
of 2 different segments in parallel streams
➢ Finisher method: optionally transform container object into something else
✓ Predefined collectors:

6. Date Time API

❖ For computers, kind of interpretation of time is represented by the model time as single
large number representing a point on continuous timeline
❖ The origin of this timeline called epoch has be arbitrary set at midnight on January 1st
1970 (same convention used in UNIX referred to as Unix time)
❖ In case of computers epoch is considered as starting point sp time is measure forward and
also backward. So any time is considered as single large number on the timeline line
number of seconds elapsed since epoch time is referred as zero

❖ UTC coordinated universal time:


✓ International time standard
✓ Used by servers air traffic control intl space station
❖ Java 8 date and time API used standard called ISO 8601 international standard based on
elliptic Gregorian calendar

6.1. Date and Calendar classes


❖ Commonly used classes

6.2. New Date Time API (Java 8)


❖ Part of java.time package
❖ Based on ISO 8601
❖ Mostly immutable classes (thread safe)
❖ No public constructors static factories (of method)
❖ Commonly used classes

❖ ISO 8601 format:


7. JVM Internals
❖ JVM is cornerstone of java platform. It helps java to use some of its goals like platform
independence security and very fast execution
❖ It’s an incredibly very tested and very optimized runtime environment with excellent
concurrency support which is critical when develop large scale systems
❖ JVM has few core responsibilities and they include loading and interpreting of java byte
code security and automatic memory management.
❖ When we discuses JVM there are 3 things part into it:
✓ JVM specification: it’s simply specification that describes JVM features and how
it should work and specify instruction set. Anyone can use this specification to
implement their own JVM
✓ Concrete implementation of JVM specification: it includes oracle hotspot and
IBM JVM
✓ Runtime instance: its instance of concrete JVM implementation. When we run
java program from command line runtime instance of JVM is created and then
loaded into memory before that program can be run.
❖ This illustration we present all components in JVM:

7.1. Lifetime of a Type


❖ In this chapter we are discussed about 2 component called ‘class loader’ and ‘byte code
verifier’
❖ This is lifetime of any type:

✓ Let’s consider class called hello and let’s assume that this class been accessed for
the very first time which means that it’s either been run from the command line or
it’s been accessed in some way from some other class (used by class loader)
 When class loader has to load this class it searches the class path to see
where we can find this class
 Ones it find this class it load corresponding byte code into memory
 And after that it generate something called class object which is the output
of the loading step (contain meta information like class name and names
of any of super classes and method names …)
 After all that class loader will simply create class object (java.lang.Class)
from memory and it would use it
✓ In that case (accessed for very first time) we need to load this class into memory
in JVM does that
✓ It checks that whether this class is well formed or not? (that is whether it’s
obeying the language rules of java)
 It’s done by compiler when .class file is generated
 Verification is performed by component called byte verifier
 Why is doing one more time: the reason is this class hello. class could
have been downloaded across the network and it could have been compiled by
host compiler whose intention is to perform some malitions actions on the system
on which it’s going to be executed
 After check if it’s not perform so it reject this class which mean it’s not
going to executed
✓ If the file is well formed, then it allocates spaces for any of static variables within
this class and it’s also go to initialize those variables with default values
✓ If class access for very first time, by creating an instance of it then all of instance
variables will also be allocated space and initialized with default values
✓ Load any reference classes. This class could be accessing other variables or
methods in other classes or creating instances of other classes. So in this case we
want to load all classes that are being referenced from this class
✓ Initialize variables: earlier we create space for static variables and initialize with
default values so here we going to override those default values with actual user
defined initial value (in initialize blocks)
➔ If we load class, then super class will be loaded before this class will be loaded
➔ If type to loaded is interface then it will be loaded and not initialized and will be
initialized only if one of its static methods are accessed or field initialized via method
✓ Finally the type will be executed

7.1.1. Loading
❖ Here is illustration of class loading process:

✓ Whenever type is accessed be class or interface, the class loader first checks if
corresponding class object is already on the heap.
➢ If it is on the heap it returns the class object
➢ Otherwise it means the type is accessed for the very first time
✓ The class loader tries to locate the corresponding .class file using something
called parent delegation model
➢ If .class is found then class loader loads the corresponding byte codes
and creates class object and returns it and the class will stored on the
heap for future use
➢ If .class file not found the exception called class not found exception is
generated
❖ Parent delegation model is:
✓ Java has multiple class loaders each loading classes from different repositories
✓ Bootstrap class loader (primordial class loader): It loads all core java API
classes (jre/lib/rt)
✓ Extension class loader: which is responsible for loading classes from standard
java extension API’s which is in (jre/lib/ext/*)
✓ Application/system class loader: loads application classes from the class path
➢ In application class loader we have user defined class loader: they are
custom class loaders created by regular developers and they are used to
load classes from non standard user defined sources like encrypted files
databases and so on. They extends abstract class called
java.lang.ClassLoader
❖ First time loading of class when:
✓ New instance are created
✓ Invoking static method
✓ Accessing static fields
➢ Exception compiles time constants. If one class use compile time
constants then they’re copied where they are used (into .class file)
✓ Subclass is loaded
✓ It is run from command line
✓ Via reflection
❖ First time loading of interface when:
✓ Invoking static method (from java 8)
✓ Accessing static fields
✓ Subclass is loaded or sub interface is loaded
✓ Run from command line (java 8)
✓ Reflection
❖ Class object (output of class loading process):
✓ all objects that will created from particular class is always done using class object
of that class
✓ have meta-information’s:
✓ classes that can be loaded are any of these types
➢ class
➢ interface
➢ primitives
➢ void
➢ arrays: all arrays of same dimensions and same type have the same
class object (length of array haven’t any role here)

7.1.2. Linking
❖ Linking is the most complicated of the 3 stages of the lifetime of type and it includes 3
steps:
✓ Verification
✓ Preparation
✓ Resolution (optional)
❖ Verification step:
✓ Verifies the loaded class is not malformed that is it conforms to the java language
rules
✓ This is needed as the class file might have been loaded from across network or it
could be user defined class from local file system
✓ In either case JVM does not trust those classes as they come from less trustworthy
resources they could have been generated from hostile compiler whose intention
is to perform some malicious actions
✓ Byte code verification is done by component byte code verifier.

➢ Once code is successfully verified by byte code verifier only then code
is considered safe to be run by JVM and it would allowed it’s execution engine to
perform at optimum level as it doesn’t have to perform any further security checks
➢ If verifier has problem it rejects mal formed class and throws exception
✓ Some verifications checks
➢ Final class are not sub classed
➢ Final method are not overridden
➢ No illegal method overloading
➢ Byte code integrity statement like if condition does not send control
beyond method boundary
❖ Preparation step:
✓ Allocate space for static fields and initialize them with default value
✓ If there isn’t enough memory then OutOfMemoryError will be generated
✓ If class loaded because instance of it is created then space will be allocated with
for instance fields also and they also be initialized with default values
 Static fields will be initialized before instance field are initialized
❖ Resolution step (optional step):
✓ Resolves symbolic references (reference fields and methods from other classes)
and load them so that current class can use them
✓ Symbolic references
➢ Logical references
➢ Are stored in constant pool(area of .class file) constant pool includes
compile time constants and string literals too
➢ At runtime, referenced class are loaded into memory after their
corresponding symbolic references within current class will be replaced
with direct references to their actual location in the memory

✓ Dynamic linking: can happen in 2 ways depending on JVM implementation


➢ Eager loading: resolution happens after preparation step that is all
classes referenced by current class will also be loaded which means that they get
loaded and initialized before current class itself initialized
➢ Lazy loading: resolution happens after initialization (on diamond)
 Typically JVM implement lazy loading and that’s because you don’t
have loaded class until you really needed sometimes certain statements may never
executed
✓ When resolving references resolution also ensures that current class has
permission to access referenced class also resolution ensures that the fields
exist in those classes and they have correct type also and current class has
permission to access them So resolution has perform some of verification

7.2. Reflection
❖ Reflection allows programs to do 2 things:
✓ It allows programs to introspect known or unknown code. For example it
allows us to you what methods fields and constructors are defined in particular
class or an object without even known their names at compile time
 You can get all this meta-information directly at runtime
 Al you need is class name as string or object reference or even name of
interface and you can get all these meta-information
✓ Allows affecting runtime behavior too. For example if you just know the class
name at runtime you will be able to load the class create instance of the class
and even invoke certain methods on that instance and even set or get value of
fields of that instance
❖ Reflection use cases:
✓ IDE like eclipse use reflection to offer that class browsing capability
✓ Processing annotations (meta data added to source code): for example ORM
framework like hibernate uses reflection to identify members of class that are
annotated
✓ When create dynamic proxies:
➢ For example we have student class with method update profile
➢ Let’s say we want to assume the time it takes to execute this method
and maybe we also want to do same for many of our classes
➢ In such case, we can drop instance of student class in dynamic proxy
and that proxy provide additional logic to measure method execution
time
➢ Client can invoke update profile method on dynamic proxy and the
proxy would intern invoke update method in student class
❖ In last lesson we are know that class object is all about this meta-information. Sp we are
going to use class object here in reflection.

✓ It’s not just JVM class loader that make use of class object but even we
developers can make use of class object while using reflection
✓ The entry point of reflection is by getting reference to the class object
✓ Reflection is not possible without access to class object
✓ Reflection is not constrained to just this class called Class but class from
java.lang.reflect package are also part of reflection
❖ How we can access class object:
✓ There are 3 ways to access class object
➢ Using object reference:

 When invoke get class to set interface we get class for hash set class
 Example for using

➢ Using class.forName:

▪ Argument must be fully qualified class name


▪ Doesn’t work with primitives
▪ Example:
➢ Using class literals:
▪ Append .class to type name
▪ Works with class interfaces arrays and primitives
▪ Example:

✓ For Name vs. class literals

✓ There are field called TYPES in every field for primitives and void and it
returns class object for corresponding primitive
➢ Boxed primitives have TYPE field

➢ Void have TYPE

➔ .class is preferred

7.3. Runtime Data Areas


❖ It’s memory which is associated with JVM
❖ Any process when it starts gets chunk of memory from underling operating system. This
memory is referring to native memory.
❖ The process will have its own virtual address space which maps to physical memory or
any file or any addressable storage.
❖ This virtual address space have 2 parts:
✓ User space (User programs): is unique to each process and that’s basically the
native memory too and that’s where user program are stored
✓ Kernel space: is kernel resides and this base is shared by all the processes
 In 32 bit windows by default the process gets 2GB of user space and 2GB of kernel
space
 In 32bit Linux machine by default process gets 3GB user space and 1GB kernel space
❖ As JVM is also process, it also gets its share of native memory which is splits into
multiple sub area for storing different things
✓ Native heap = user space – java heap and it contains sometimes many others
areas. it can includes stuff like code that is compiled by just in time compiler
✓ Java heap: it basically stored java objects (incl. arrays and class objects)
 Setting proper java heap size is very important for good performance on
production system
✓ Method area: contains class data which would be all data contain to class that
include meta information of the class like fully qualified class name super class
name … it also include actual byte code of each method
 Method area and java heap are shared all the threads
➔ There are certain things specific to each thread
✓ Stack: it includes method invocation state that is the order of invocation of
methods. It would also includes information about local variables within each
method
❖ How thinks get populated on heap and method area:
✓ Objects are created on heap and these objects would include regular class
instances via new operator arrays and also class objects
✓ When we say objects are stored on the heap means that we are mainly talking
about the instance data present within those objects that is instance data resize ob
the heap
✓ JVM allocate space to an object based on how much instance data is contains
which depend on number of instance variables and also data type of those instance
variables
✓ Any class data (like behavior, meta-information like field name/type ..) will be
stored in the method area
✓ Method area is all about classes while heap is all about objects
✓ When create instance of class:

➢ Class loader check if class object for particular class is already on the heap
➢ If it’s not there it would then create class object on the heap and the
corresponding class data in method area
➢ JVM would class new instance of that class and would stored on the heap
➢ If new object of this class be created the only object would be created and
store on the heap
❖ Method area: it contain class data which include
✓ Meta information of the type like fully quailed name of type, super class super
interface, is class or interface, info. Type modifiers like abstract final and public
 class object uses class data stored in method area to access to these
information’s
✓ Reference to class object.
✓ Field info like static and instance variables: it include field name type and any
associated modifiers like static …
 If field is instance variable then it value stored on the heap
 If it is static variable then it’s value stored on method area
 If it is object then it stored on heap but its reference stored in method area in
case of static variables
✓ Runtime constant pool: its runtime version of constant pool. It includes literals or
symbolic references
✓ Method info like method name, return type, num and type of parameters,
modifiers method byte code
✓ Method table: array of references to instance methods (not static methods) it used
during method invocation process. Each reference pointer to method byte code
stored on method area

7.4. Garbage Collection


❖ When we create an object using new keyword JVM determine the amount of heap
memory needed for storing the object and it allocate much amount of memory
❖ But as more and more objects are created then it would also result in allocating more
memory.
 If we keep creating objects in this way eventually we may run out of memory and
we will get errors like out of memory array
 So we need to realize or reclaim memory when objects are no longer required
❖ In java its take care of automatically by the garbage collected
❖ Explicit memory management:
✓ In language like C or C++, programmer has to explicitly allocate memory when
create an object and similarly when these objects are not needed anymore they
have to explicitly free up the space taken by those objects
✓ That would certainly help in developing efficient applications
✓ But in large projects in such memory manipulation is not done right (corrupted in
some way) then it could resulting serial issues like crashing the program or
program works incorrectly
✓ Memory corruption errors:
➢ Memory leak: happen when unused objects are never freed. After that we
will have out of memory and program will stop
➢ Dangling reference: reference to area of memory that has already been
reclaimed. For example 2 separate components shared same object if one
of them is done using that object then it may free of memory occupied by
that object and that ease of memory might get allocated to new object. But
second component still allocated the same memory area
❖ Automatic memory management:
✓ Used in java by garbage collection which is performed by garbage collector
✓ Instead of programmers, garbage collector basically reclaims memory occupied
by dead objects. By doing so its ensure that there are no memory leaks
✓ Dead objects is really dead objects that is need 100% sure that there are no active
references to that particular object
✓ Abandoned objects examples:
➢ Going out of scope: if we terminate block all local variables in this block
are abandoned objects

➢ Assigning new object

➢ Assigning null:

➢ Will not have any active references


✓ Garbage collection specifics:
➢ Implemented as part of language itself (like java) or may added as library
too
➢ Runs in background in low priority thread
➢ No guaranties when garbage runs and programmers has little control on
when it would run (runs when there is limited memory)
➢ We can run garbage collection by one of these approaches :

❖ You can see garbage collection algorithms in INTERNET.


❖ There all many commands line related to JVM by them you can configure heap
allocations (they are arguments can added to java command) (heap related options)
✓ -Xms13m: minimum amount of memory that would be allocated to heap memory
(13 mega bits)
✓ -Xmx13m: maximum amount of memory that would be allocated to heap memory
(13 mega bits)
✓ -XX:+PrintGCDetals: we want to print garbage collections details. Summary of
heap memory
✓ -XX:+UseSerialGC: force JVM to use serial garbage collection (serial collector).
❖ Item 6: eliminate obsolete object references:
✓ Java program can have memory leaks despite all efforts of GC
✓ It’s about avoiding memory leaks
✓ Obsolete object references (use stack last in first out data structure)
➢ In this example when we invoke pop method from stack data structure the
method will return the last element and decrement the size of the array.
➢ But the last element does not remove their reference is present and not
remove (this is obsolete object reference)
➢ The solution for this is to null out the obsolete references like in out
example

➢ You shouldn’t go about nulling every object reference and that would be
unclean code
➢ But you should use nulling when you’re your program is managing its
own memory like in the case of stack example here
✓ You can use performing monitoring tools to remove any memory leaks in you
program
➢ JProfiler: This is a very useful tool. For couple of my projects, it helped
me in identifying code that was pretty slow. It will help you identify
performance at a method level (e.g., how much time a method is taking).
Subsequently, I was to use better algorithms to speed up the process. You
can try out their trial version
➢ Plumbr: they claim that they are very good at identifying memory leaks.
They have really good resources on their site. You should be able to use
their trial version too

7.5. Stack
❖ Stock store all information about method that are getting invoked and executed (methods
that executed now and not that should be executed or finished of its execution)
❖ It also store all information about local variables in each of executing methods
❖ It’s basically LIFO data structure
❖ Like heap and method area, JVM creates stack for each newly created thread
✓ When method is invoked, an entity called stack frame representing that method
is created and pushed on the top of the stack
✓ If this method invokes another method, then new stack frame will be created
for that new method and that stack frame will also be pushed on the top of the
stack
✓ Frame is pop of the stack when the method invocation completes either
normally or when through some kind of error (in this step, all local variable for
this popped method are considered like dead objects and trailed with garbage
collection)
✓ If local variable is an object reference, then that variable is stored in its own
stack frame well the object is referencing will be stored on the heap

❖ Content of stack frame: it contain 3 things

✓ Local variables array:


➢ Array that stores all local variables in the method.
➢ Since method parameters are also local variables they also get store here
before local variables in the array
➢ if its instance method, index 0 in the array is reference to this that is
reference to current object on the heap
➢ it include also return address its memory address of the next instruction in
the calling method
✓ Operant stack: similar to registers in CPU

✓ Reference to runtime constant pool of the class of the current method

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy