Understanding the Java "main()" Method — "public static void main(String[] args)" Every Java program starts execution from the main() method. When you run a Java program, the JVM (Java Virtual Machine) looks for this method as the entry point. If a program does not contain a valid "main()" method, the JVM will not start execution. The commonly used syntax is: public static void main(String[] args) Each word in this declaration has a specific purpose: • public → Access modifier that allows the JVM to call the method from outside the class. If it is not public, the JVM cannot access it. • static → Allows the method to be called without creating an object of the class. The JVM can directly invoke the method when the program starts. • void → Specifies that the method does not return any value. Once the main method finishes execution, the Java program terminates. • main → The method name recognized by the JVM as the starting point of the program. Changing this name prevents the program from running. • String[] args → An array that stores command-line arguments passed when running the program. Example: class Example { public static void main(String[] args) { System.out.println("Hello, Java!"); } } Java also allows equivalent forms like: public static void main(String args[]) public static void main(String... args) All of these work because the parameter is still treated as a String array. Key Takeaway: The "main()" method acts as the entry point of a Java application, allowing the JVM to begin executing the program. #Java #JavaProgramming #CoreJava #JVM #BackendDevelopment #Programming #LearnToCode
Java Main Method: Entry Point for JVM Execution
More Relevant Posts
-
Java Garbage Collection: Things Many Developers Don’t Realize When we start learning Java, Garbage Collection (GC) is often explained very simply: "Java automatically removes unused objects from memory." While that statement is true, the reality inside the JVM is much more interesting. After working with Java and studying JVM behavior, I realized there are several important things many developers overlook. Here are a few insights about Java Garbage Collection: 🔹 1. Objects are not removed immediately Just because an object is no longer used doesn’t mean it is deleted instantly. Garbage Collection runs periodically, and the JVM decides when it is the right time to clean memory. 🔹 2. GC is based on Reachability, not null values Setting an object to "null" doesn’t automatically delete it. An object becomes eligible for GC only when no references point to it anymore. Example: User user = new User(); user = null; Now the object may become eligible for GC. But the JVM will clean it later when GC runs. 🔹 3. Most objects die young In real applications, many objects exist only for a short time. Because of this, the JVM uses Generational Garbage Collection: • Young Generation → short-lived objects • Old Generation → long-lived objects This design makes memory management more efficient. 🔹 4. "System.gc()" does not guarantee GC Many developers think calling this will force GC: System.gc(); But in reality, it only suggests the JVM run GC. The JVM may still ignore it. 🔹 5. Memory leaks can still happen in Java Even with automatic garbage collection, memory leaks can occur if objects are still referenced. Common examples: • Static collections holding objects • Unclosed resources • Caches without eviction policies Key takeaway... Garbage Collection is one of the biggest reasons Java is reliable for large-scale systems. But understanding how the JVM actually manages memory helps developers write more efficient and scalable applications. Curious to hear from other developers: What was the most surprising thing you learned about Java Garbage Collection? #Java #JVM #GarbageCollection #BackendDevelopment #SoftwareEngineering #JavaDeveloper
To view or add a comment, sign in
-
Generic Classes in Java – Clean Explanation with Examples 🚀 Generics in Java are a compile-time type-safety mechanism that allows you to write parameterized classes, methods, and interfaces. Instead of hardcoding a type, you define a type placeholder (like T) that gets replaced with an actual type during usage. 🔹Before Generics (Problem): class Box { Object value; } Box box = new Box(); box.value = "Hello"; Integer x = (Integer) box.value; // Runtime error ❌ Issues: • No type safety • Manual casting required • Errors occur at runtime 🔹With Generics (Solution): class Box<T> { private T value; public void set(T value) { this.value = value; } public T get() { return value; } } 🔹Usage: public class Main { public static void main(String[] args) { Box<Integer> intBox = new Box<>(); intBox.set(10); int num = intBox.get(); // ✅ No casting Box<String> strBox = new Box<>(); strBox.set("Hello"); String text = strBox.get(); } } 🔹Bounded Generics: 1.Upper Bound (extends) → Read Only: Restricts type to a subclass List<? extends Number> list; ✔ Allowed: Integer, Double ❌ Not Allowed: String 👉 Why Read Only? You can safely read values as Number, but you cannot add specific types because the exact subtype is unknown at compile time. 2.Lower Bound (super) → Write Only: Restricts type to a superclass List<? super Integer> list; ✔ Allowed: Integer, Number, Object ❌ Not Allowed: Double, String 👉 Why Write Only? You can safely add Integer (or its subclasses), but when reading, you only get Object since the exact type is unknown. 🔹Key Takeaway: Generics = Type Safety + No Casting + Compile-Time Errors Clean code, fewer bugs, and better maintainability - that’s the power of Generics 💡 #Java #Generics #Programming #SoftwareEngineering #Coding
To view or add a comment, sign in
-
Day 47 – Java 2026: Smart, Stable & Still the Future Static Initializer in Java (ClassLoader & Memory Explained) A static initializer block in Java is used to initialize static variables. It executes only once when the class is loaded into memory by the JVM ClassLoader, before any object is created. It is useful when initialization requires logic or multiple statements, not just a direct assignment. class Example { static int number; static { System.out.println("Static block executed"); number = 50; } public static void main(String[] args) { System.out.println("Main method started"); System.out.println("Number: " + number); } } Output Static block executed Main method started Number: 50 How it Works in JVM When a Java program runs, the JVM loads classes using the ClassLoader in three steps: Loading – .class file is loaded into JVM memory (Method Area). Linking – JVM verifies the class and allocates memory for static variables. Initialization – static variables and static blocks execute. Memory Structure Method Area Class metadata Static variables Static blocks Heap Objects created using new Stack Method execution frames Static members are stored in the Method Area because they belong to the class, not to objects. Key Point A static initializer runs only once during class loading, ensuring efficient one-time setup such as configuration loading, driver initialization, or cache preparation. #Java #JavaDeveloper #JVM #ClassLoader #BackendDevelopment #Programming#100series
To view or add a comment, sign in
-
🚀 Java 25 Innovation Alert: Compact Object Headers (COH)!🚀 If you’re working with large-scale Java applications, this JVM feature is a game-changer you might not know about — but it silently makes your apps faster, leaner, and more efficient. Let me break it down 👇 ✨ What are Compact Object Headers? In Java, every object has a little metadata block called the object header — storing info like: 🧠 Object hash codes 🗂️ Garbage Collection (GC) data 🔐 Lock states for synchronization 📚 Class metadata pointers Traditionally, these headers can take 16 to 24 bytes each on a 64-bit JVM — and when you have millions (or billions!) of objects, memory usage quickly balloons. 🔧 Java 25 to the rescue! With Compact Object Headers, the JVM compresses these metadata pieces: Mark Word (GC info, locks, hash) gets squeezed into fewer bytes Klass Pointer (class info) uses half the space Rare flags move out of the header into auxiliary space 💡 The result? Object headers shrink to ~8–12 bytes on average. 🔥 Why this matters: 🏋️ Save gigabytes of memory in large applications ⚡ Boost CPU cache locality & speed up access 🧹 Lower GC overhead, improving pause times and throughput 💻 Free up heap space for your actual data and logic ⚙️ How to enable COH in Java 25: By default, if your heap is under 32GB and compressed pointers (OOPs) are enabled, COH kicks in automatically. You can manually turn it on with: -XX:+UseCompactObjectHeaders Check it with: java -XX:+PrintFlagsFinal -version | grep CompressedOops ✅ Takeaway: You don’t have to change your code—this JVM-level magic makes your Java apps more memory-efficient and performant right out of the box. If you’re architecting Java systems at scale, COH is a subtle but powerful tool in your toolbox. #Java #JVM #Performance #MemoryManagement #Java25 #TechTips #SoftwareEngineering #Programming
To view or add a comment, sign in
-
-
#Java strings are length-prefixed objects, not null-terminated sequences, it is a deliberate move towards safer and more predictable string handling, if you were hoping for a hidden \0 at the end, I’m afraid Java decided that was someone else’s problem decades ago. Java strings are not null terminated, they are instances of String, not raw character arrays with a sentinel value tacked on the end, instead of scanning memory until a zero byte shows up, Java stores the length explicitly as part of the object state so when you call length(), the JVM does not go hunting for a terminator like it is 1972, it simply reads a field. This design choice is not just aesthetic, it is architectural, in C-style null terminated strings, determining length is an O(n) operation because you must traverse until \0 appears. Java avoids that entirely, length is O(1), which is exactly what you want in a language that pretends to care about abstraction and performance. Internally, Java strings are backed by arrays, historically char[] and more recently byte[] with a coder flag for compact storage, the crucial detail is that the array is paired with metadata, including length, so the runtime always knows the bounds without relying on a terminator. In Java, the null character \u0000 is just another character, you can place it in the middle of a string and nothing dramatic happens, no truncation, no existential crisis, this alone makes null termination impractical as a contract, since the language explicitly allows that value inside strings. Null terminated strings have a long and rather embarrassing history of buffer overflows and off-by-one errors because developers forget to allocate space for the terminator or fail to write it, java sidesteps the entire category by design, no terminator, no dependency on sentinel correctness, fewer ways to shoot yourself in the foot. There is, however, a trade-off, when interfacing with native code via JNI, you cannot assume Java strings behave like C strings, you must pass both pointer and length explicitly or use conversion helpers, aka, the #JVM will not indulge your nostalgia for null termination. https://lnkd.in/dmKXUtGf
To view or add a comment, sign in
-
🚀 Java Series – Day 28 📌 Reflection API in Java (How Spring Uses It) 🔹 What is it? The **Reflection API** allows Java programs to **inspect and manipulate classes, methods, fields, and annotations at runtime**. It allows operations like **creating objects dynamically, invoking methods, and reading annotations** without hardcoding them. 🔹 Why do we use it? Reflection helps in: ✔ Dependency Injection – automatically injects beans ✔ Annotation Processing – reads `@Autowired`, `@Service`, `@Repository` ✔ Proxy Creation – supports AOP and transactional features For example: In Spring, it can detect a class annotated with `@Service`, create an instance, and inject it wherever required without manual wiring. 🔹 Example: `import java.lang.reflect.*; @Service public class DemoService { public void greet() { System.out.println("Hello from DemoService"); } } public class Main { public static void main(String[] args) throws Exception { Class<?> clazz = Class.forName("DemoService"); // load class dynamically Object obj = clazz.getDeclaredConstructor().newInstance(); // create instance Method method = clazz.getMethod("greet"); // get method method.invoke(obj); // invoke method dynamically } }` 🔹 Output: `Hello from DemoService` 💡 Key Takeaway: Reflection makes Spring **dynamic, flexible, and powerful**, enabling features like DI, AOP, and annotation-based configuration without manual coding. What do you think about this? 👇 #Java #ReflectionAPI #SpringBoot #JavaDeveloper #BackendDevelopment #TechLearning #CodingTips
To view or add a comment, sign in
-
-
Day 48 – Java 2026: Smart, Stable & Still the Future Non-Static Initializer in Java (Instance Initializer Explained) A non-static initializer block (also called an instance initializer block) is used to initialize instance variables of a class. Unlike static blocks, it executes every time an object of the class is created. It runs before the constructor but after the object memory is allocated in the heap. Syntax { // initialization code } This block does not use the static keyword because it works with object-level variables. Example class Example { int number; { System.out.println("Non-static initializer executed"); number = 100; } Example() { System.out.println("Constructor executed"); } public static void main(String[] args) { Example obj1 = new Example(); Example obj2 = new Example(); } } Output Non-static initializer executed Constructor executed Non-static initializer executed Constructor executed Execution Flow in JVM Class is loaded by the ClassLoader. Memory for the object is allocated in the Heap. Non-static initializer block executes. Constructor executes. Object becomes ready for use. Flow: Object Creation ↓ Memory allocated in Heap ↓ Non-static initializer executes ↓ Constructor executes Memory Structure Method Area Class metadata Static variables Static methods Heap Object instance variables Non-static initialization Stack Method execution frames Non-static initializers belong to object creation, so they work with Heap memory. When It Is Used Non-static initializer blocks are useful when: Common initialization code is required for all constructors Reducing duplicate logic inside multiple constructors Preparing instance-level configuration before constructor logic runs Key Point A non-static initializer executes every time an object is created, making it useful for object-level initialization before the constructor runs. #Java #JavaDeveloper #JVM #OOP #Programming #BackendDevelopment
To view or add a comment, sign in
-
🚀 Understanding the Diamond Problem in Java (with Example) The Diamond Problem happens in languages that support multiple inheritance—when a class inherits the same method from two different parent classes, causing ambiguity about which one to use. 👉 Good news: Java avoids this completely for classes. 🔒 Why Java Avoids It - Java allows single inheritance for classes → no ambiguity. - Uses interfaces for multiple inheritance. - Before Java 8 → interfaces had no implementation → no conflict. - After Java 8 → "default methods" can create a similar issue, but Java forces you to resolve it. --- 💥 Problem Scenario (Java 8+ Interfaces) interface A { default void show() { System.out.println("A's show"); } } interface B { default void show() { System.out.println("B's show"); } } class C implements A, B { // Compilation Error: show() is ambiguous } 👉 Here, class "C" doesn't know whether to use "A"'s or "B"'s "show()" method. --- ✅ Solution: Override the Method class C implements A, B { @Override public void show() { A.super.show(); // or B.super.show(); } } ✔ You explicitly choose which implementation to use ✔ No confusion → no runtime bugs --- 🎯 Key Takeaways - Java design prevents ambiguity at the class level - Interfaces give flexibility but require explicit conflict resolution - Always override when multiple defaults clash --- 💡 If you think Java is "limited" because it doesn’t allow multiple inheritance… you're missing the point. It’s intentional design to avoid chaos, not a limitation. #Java #OOP #Programming #SoftwareEngineering #Java8 #CleanCode
To view or add a comment, sign in
-
-
𝗘𝘃𝗲𝗿 𝗵𝗲𝗮𝗿𝗱 𝗼𝗳 𝗮 𝘁𝗵𝗿𝗲𝗮𝗱 𝘄𝗮𝗸𝗲 𝘂𝗽...𝘄𝗶𝘁𝗵𝗼𝘂𝘁 𝗯𝗲𝗶𝗻𝗴 𝗻𝗼𝘁𝗶𝗳𝗶𝗲𝗱? No notify(), no interrupt() and yet it continues execution. That’s where I learnt about the 𝗦𝗽𝘂𝗿𝗶𝗼𝘂𝘀 𝗪𝗮𝗸𝗲𝘂𝗽 in Java threads. 𝗔 𝗦𝗽𝘂𝗿𝗶𝗼𝘂𝘀 𝗪𝗮𝗸𝗲𝘂𝗽 in Java threads occurs when a thread in the waiting state wakes up without being notified or without any explicit thread method. 𝗪𝗵𝘆 𝗱𝗼𝗲𝘀 𝗶𝘁 𝗵𝗮𝗽𝗽𝗲𝗻? - The JVM does not control thread execution entirely; execution relies on the operating system. OS thread systems (like pthreads) wake up threads randomly. - It is by design; Java explicitly allows this behaviour. - Java and OS don't guarantee threads wake up when notified, as it can impact the overall performance. 𝗪𝗵𝗮𝘁 𝗵𝗮𝗽𝗽𝗲𝗻𝘀 𝗶𝗻𝘁𝗲𝗿𝗻𝗮𝗹𝗹𝘆? 1. lock.wait() is called 2. The thread releases the monitor lock and goes to the waiting state. 3. JVM/OS maintains a wait queue for the object. 4. Ideally, threads wakes when notify()/notifyAll() methods is called. BUT JVM/OS can remove the thread from the wait queue randomly and put it into the runnable state. How to prevent issues due to spurious wakeups? Never use "if" with "wait()" method, always use "while" public synchronized void consume() throws InterruptedException { if (queue.isEmpty()) { wait(); // may wake up spuriously } int item = queue.remove(); } In case of a spurious wakeup, queue.remove() will execute directly. If the queue is empty, it will throw an exception. public synchronized void consume() throws InterruptedException { while (queue.isEmpty()) { wait(); // may wake up spuriously } int item = queue.remove(); } In this case, even if a spurious wakeup happens, the while loop rechecks the condition. If the queue is still empty, it goes back to the waiting state again, preventing any exceptions/errors. Have you ever faced a spurious wakeup in production or in your personal projects? Let's discuss in comments.
To view or add a comment, sign in
-
🔍 Understanding Arrays in Java (Memory & Indexing) Today I learned an important concept about arrays in Java: Given an array: int[] arr = {10, 20, 30, 40, 50}; We often think about how elements are stored in memory. In Java: ✔ Arrays are stored in memory (heap) ✔ Each element is accessed using an index ✔ JVM handles all memory internally So when we write: arr[0] → 10 arr[1] → 20 arr[2] → 30 arr[3] → 40 arr[4] → 50 👉 We are NOT accessing memory directly 👉 We are using index-based access Very-Important Point: 👉 Concept (Behind the scenes) we access elements using something like base + (bytes × index) in Java 💡 Let’s take an example: int[] arr = {10, 20, 30, 40, 50}; When we write: arr[2] 👉 We directly get 30 But what actually happens internally? 🤔 Behind the scenes (Conceptual): Address of arr[i] = base + (i × size) let's suppose base is 100 and we know about int takes 4 bytes in memory for every element :100,104,108,112,116 So internally: arr[2] → base + (2 × 4) Now base is : 100+8=108 now in 108 we get the our value : 30 Remember guys this is all happening behind the scenes 👉 You DON’T calculate it 👉 JVM DOES it for you 👉 But You Still need to know ✔ Instead, it provides safety and abstraction 🔥 Key Takeaway: “In Java, arrays are accessed using indexes, and memory management is handled by the JVM.” This concept is very useful for: ✅ Beginners in Java ✅ Understanding how arrays work internally ✅ Building strong programming fundamentals #Java #Programming #DSA #Coding #Learning #BackendDevelopment
To view or add a comment, sign in
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development