Core java things.
✅ JDK (Java Development Kit)
Includes:
➔ Development tools (for compiling & debugging)
➔ JRE (for running Java programs)
Main Use: To develop Java applications.
✅ JRE (Java Runtime Environment)
Includes:
➔ Java Class Libraries
➔ JVM (Java Virtual Machine)
Main Use: To run Java applications (but not develop/compile them).
✅ JVM (Java Virtual Machine)
Main Role:
➔ Executes compiled Java bytecode (.class files).
➔ Platform-independent layer that actually runs Java programs.
✅ Program Flow Example:
1. Source Code:
First.java (written by developer)
2. Compile:
javac First.java → produces First.class (bytecode)
3. Run:
java First → JVM executes the First.class bytecode
✅ Commands:
javac -version → Shows Java Compiler version (from JDK)
java -version → Shows JVM version (from JRE)
Inner Class?
Outer class can have inner class
Why do we need inner class?
🔶 What is an Inner Class?
An Inner Class is a class that is defined inside another class.
The class that contains the inner class is called the Outer Class.
Inner classes are used for grouping logically related classes
together and to access members of outer class easily.
🔶 Why do we need Inner Classes?
1. Logical Grouping: If a class is useful only to its outer class, it's better
to keep it inside.
2. Encapsulation: Hide inner workings from outside code.
3. Easy Access: Inner class can directly access private members of outer
class.
4. Event Handling / Callbacks: Common in GUI frameworks (e.g.,
ActionListener).
🔶 Types of Inner Classes:
Type Description
1. Member Inner
Regular class defined inside another class.
Class
2. Static Nested
Declared static, doesn't need outer class object.
Class
3. Local Inner
Defined inside a method of outer class.
Class
4. Anonymous Class without a name, used for instant use (often for
Inner Class interfaces/abstract classes).
Nested Inner class-
class Outer{
int x=10;
class Inner{
int y=20;
public void disp(){
System.out.println(x+" "+y);
}
}
public void display(){
Inner i = new Inner();
i.disp();
System.out.println(x+" from outer "+i.y);
}
public class NestedInner {
public static void main(String[] args) {
Outer o =new Outer();
o.display();
Outer.Inner iobj= new Outer().new Inner();
iobj.disp();
}
}
Inner classes can access the method of outer class but
For outer classes To access the inner class methods, the outer class
must explicitly create an object of the inner class.
Outer.inner innerObj=OuterClass().innerClass()
Now 2 class created Outer.class and Outer#inner.class
class Outer1{
void Display(){
//local inner class
// outside this method inner class is not useful
// need 1 - when writing a class which implementing
// a interface and that class useful for only a method
// not outside that method
// need 2 - when writing a class which inheriting a class
// used in builtin package of java
class Inner1{
void innerDisp(){
System.out.println("hello local inner");
}
}
Inner1 i1= new Inner1();
i1.innerDisp();
}
}
abstract class My{
abstract void abstrdisplay();
}
class Outer2{
//anonymous innerclass-
// class defined at time of object creation
// means object creation and class defined at same time
// useful for interface and abstract classes
//need?- if have to implement a interface
// and its usage is limited you dont need to create
//seperate class and implement it there
public void outerMethod{
//not creating object
My myclassobj=new My() {
@Override
void abstrdisplay() {
System.out.println(" abstract class overriden");
}
};
myclassobj.abstrdisplay();
}
}
Anonymous inner classes in Java can indeed access the members of their
enclosing outer class. This feature allows for tight coupling of functionality,
enabling the inner class to utilize and modify the outer class's properties and
methods easily.
//as nested inner class depend on outer class
// and they are not accessible without outerclass object
//thus come STATIC INNER CLASS
class Outer3{
static int x_static=20;
int y_instance=21;
static class inner3{
//STATIC inner class can access only static member of
//outer class. cannot access non-static method and var
void display(){
System.out.println(x_static);
//System.out.println(y_instance); -CANNOT ACCESS
}
}
public static void main(String[] args) {
// now here no need of new Outer().new Inner()
//no need to create outer class object
Outer3.inner3 staticinnerObj=new Outer3.inner3();
staticinnerObj.display();
}
}
✅ Summary:
Inner Class is a class inside another class.
Helps in grouping, encapsulation, and accessing outer members.
4 types: Member, Static Nested, Local, Anonymous.
Anonymous Inner Class Special Case
Anonymous inner class is a nameless class you define on-the-fly.
Syntax-wise, it has to either:
1. Extend one class (and override methods), OR
2. Implement one or more interfaces.
Technically, a normal class can do this:
class MyClass extends ParentClass implements Interface1, Interface2 {}
But anonymous inner classes are meant to be quick, lightweight, and
inline so cannot do that.
Anonymous inner class ki syntax yeh bolti hai:
new ParentClass() { ... }
ya
new Interface() { ... }
Ek hi baar 'new' ke sath define kar sakte ho, isliye syntax allow nahi
karta ki tum bol sako:
new ParentClass() implements Interface { ... } // ❌ Not allowed
local inner class- cannot public, final, static BUT CAN ONLY BE USE
ABSTRACT
Inner Class
When to Use Why to Use
Type
- When inner class needs - To logically group classes that
Member
access to outer class are part of outer class-
Inner Class
instance members Improves encapsulation
- When inner class is a
Static - Saves memory (no outer
utility/helper class and
Nested instance needed)- Groups
does NOT need outer
Class related helper code
instance
Local Inner - When you need a class for - Keeps code organized &
Inner Class
When to Use Why to Use
Type
encapsulated- Prevents
one specific method/task
Class unnecessary outer exposure of
only
helper logic
- For one-time quick - Short-lived use-cases- Reduces
Anonymous implementations boilerplate code- Great for
Inner Class (interfaces, abstract classes, event handling, strategy
callbacks) patterns, etc.
Generics?
Object class – mother of all class.
It means to object of Object class we can assign any class. i.e
GENERALIZTION
Object obj=new String(“hii”);
But String str= obj not work we need String str=(string ) obj; i.e typecasting
Before java 1.8 java use Object class for generalization.
Why Generics are Better :
Without Generics With Generics
Compile-time safety (no wrong
Compiles even if types are wrong
types)
Runtime crashes Prevents mistakes at compile-
(ClassCastException) time
Manual type casting needed No casting needed
package generics;
class Data<T>{
private T obj;
public T getObj() {
return obj;
}
public void setObj(T obj) {
this.obj = obj;
}
}
class MyArray<T>{
T arrobj[]= (T[]) new Object[10];
int leng=0;
public void append(T value){
arrobj[leng++]=value;
}
public void disp(){
for (T element:arrobj){
System.out.println(element);
}
}
public class DataGenr {
public static void main(String[] args) {
Data<Integer> d=new Data<>();
d.setObj(33); // only Integer
}
}
No Parameters: In that case generic parameters will be considered as OBJECT
Ex- here the array can store anything of object type.
MyArray myArray1=new MyArray();
myArray1.append(new Integer(11));
myArray1.append(9890);
myArray1.append("trok");
Multiple Parameters: Generic class may have multiple parameters.
class MyArray2Params<T1, T2>{
Subtypes:
class MyArray2<T> extends MyArray<T>{
//if no type given then take MyArray<Object>
// if MyArray<String> then MyArray2 works for String
// if generic class extends from generic class then
// your class should generic means => class MyArray2<T> extends
MyArray<T>{
}
MyArray2<String> myArray2=new MyArray2<>();
//now both MyArray and MyArray2 become of String
Bounded Types:
class MyBoundedGenr<T extends Number>{
// now it allow T be double,float, int
// work with any class whose parent is Number
public static void main(String[] args) {
MyBoundedGenr<Float> myBoundedGenr=new MyBoundedGenr<>();
interface A{}
class B implements A{}
class C implements A{}
class MyArray1<T extends A>{ //extends work for both class and interface
class A{}
class B extends A{}
class C extends A{}
class MyArray1<T extends A>{
and it works for A,B,C
public static void main(String[] args) {
MyArray1<A> myArray1=new MyArray1();
MyArray1<B> myArray2=new MyArray1();
}
Generic Methods
//for generic method before the return type need
// to define generic type
static <E> void genricshow(E[] genrList){
for(E x: genrList){
System.out.println(x);
}
}
//variable argument generic
static <E> void genricshow2(E... genrList){
for(E x: genrList){
System.out.println(x);
}
}
public static void main(String[] args) {
genricshow(new String[]{"hii","alok","aman"});
genricshow(new Integer[]{22,33,44,5});
genricshow2("hii","byyy",3);
Also generic method works with bound type:
static <E extends Number> void genricshow(E[] genrList){
Generics Arguments – WILDCARD
Cannot do like
static void funGenericArr(MyArrayGenr<T> arrobj){
But can
static void funGenericArr(MyArrayGenr arrobj){ }
Same as static void funGenericArr(MyArrayGenr<?> arrobj){} //? Means
object
Other bounds: lowerbound- super
upperbound - extends
static void funGenericArr(MyArrayGenr<? extends Number> arrobj){
// Number is upperbound – any class that extends from Number
arrobj.disp();
}
AND
static void funGenericArr(MyArrayGenr<? super Number> arrobj){
arrobj.disp();
//Number is lowerbound -- means any class parent class of Number
or class Number BUT NOT ITS CHILD CLASS
}
This is a lower-bounded wildcard.
It means the method accepts a MyArrayGenr<T> object where T can be:
Number
or any superclass of Number (like Object)
It won’t accept subclasses like Integer, Double, etc. directly (unless wrapped
inside a MyArrayGenr<? super Number>).
Dos and Donts
1. Only extends is allowed in generic class definitions (for class and
interface also)
Class MyArr<T extends myclass2> myclass2 – may be class or interface
2. extends and super are allowed with ? in METHOD (super not used with
generic class)
3. < ? > will accept all types but cannot access.
static void fun2(MyArrayGenr<?> myArrayGenr){
myArrayGenr.append(null);
// it is not allowed <?> which type so not append string
//? can allow only null
myArrayGenr.append("hii alok");
}
4. Base type of Object should be same or <?>
MyArrayGenr<Integer>myArrayGenr2=new MyArrayGenr<Integer>();//
works as on right side same Integer
MyArrayGenr<Number>myArrayGenr3=new MyArrayGenr<Integer>(); //
not works
MyArrayGenr<?>myArrayGenr4=new MyArrayGenr<Integer>(); // works as
on right side ?
// but with ? cannot access anything
5.extends from only one class and multiple interface
class A1{}
interface B1{}
interface C1{}
class MyGenr <T extends A1 & B1 & C1>{
// first one must be class
// if MyGenr use both class and interface else error
// also multiple inheritance not allowed
// so one class + multiple interface or
// one class
// multiple interface
}
Collections in java?
Collections deal with how to arrange data in main memory.
The most easy way to arrange - array
Array – of fixed size and you cant change that size of same array for doing so
Need to create a new array and copy values there.
So if don’t know size we need variable size data structure I.e
Variable size array - ARRAYLIST , LINKEDLIST
For distinct collection = SET
For sorted collection = SORTED SET
Iterable – interface with one method iterator
Collection – interface that implements Iterable. Implemented by LIST ,
QUEUE, SET (all interface)
Class that implements LIST(ordered) – ArrayList, LinkedList, Vector, Stack
Class that implements SET (unordered,unique) – HashSet, LinkedHashSet
Interface that implements SET – SORTEDSET
Class that implements SORTEDSET – TreeSet
Class that implements QUEUE(FIFO)- PriorityQueue
Interface that implements QUEUE - Deque
Class that implements Deque-ArrayDeque
Map interface
Class that implements Map interface – HashMap, LinkedHashMap, HashTable
Interface that implements Map – SortedMap
Class that implements SortedMap – TreeMap
Collections – are generic interface – support object of any class.
List Interface
has iterator from collection unidirectional.
has list iterator from the List and it is bidirectional
Queue Interface:
Poll() – remove last element from array and null if empty
Remove() – throws NoSuchElementExceptions if empty.
Peek() - remove 1st element from array and null if empty
Element() - throws NoSuchElementExceptions if empty.
LinkedList? – A class implements List and Deque
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, Serializable
Doubly linked list
Has previous and next pointer, It not synchronized in it implementation.
insertion and deletion in constant time also size is flexible. And it is used by
Java.
ArrayDEQUE class – implemented Deque interface , operation on both ends.
They are not thread-safe; in the absence of external synchronization, they do
not support concurrent access by multiple threads.
This class is likely to be faster than Stack when used as a stack, and faster
than LinkedList when used as a queue.
PriorityQueue: - is implementing Heap which implemented Array.
Heap implementation used binary tree. So time complx = logn