4 Java Compile-time Vs Runtime Interview Q&As

During development and design, one needs to think in terms of compile-time, run-time, and build-time. It will also help you understand the fundamentals better. These are beginner to intermediate level questions.

Q1. What is the difference between line A & line B in the following code snippet?

A1. Line A, evaluates the product at compile-time, and Line B evaluates the product at runtime. If you use a Java Decompiler (e.g. jd-gui), and decompile the compiled ConstantFolding.class file, you will see whyas shown below.

Constant folding is an optimization technique used by the Java compiler. Since final variables cannot change, they can be optimized. Java Decompiler and javap command are handy tool for inspecting the compiled (i.e. byte code ) code.

Q2. Can you think of other scenarios other than code optimization, where inspecting a compiled code is useful?
A2. Generics in Java are compile-time constructs, and it is very handy to inspect a compiled class file to understand and troubleshoot generics.

Q3. Does this happen during compile-time, runtime, or both?

compile-time Vs run-time

compile-time Vs run-time

Method overloading: This happens at compile-time. This is also called compile-time polymorphism because the compiler must decide how to select which method to run based on the data types of the arguments.

If the compiler were to compile the statement:

it could see that the argument was a string literal, and generate byte code that called method #1.

Method overriding: This happens at runtime. This is also called runtime polymorphism because the compiler does not and cannot know which method to call. Instead, the JVM must make the determination while the code is running.

The method compute(..) in subclass “B” overrides the method compute(..) in super class “A”. If the compiler has to compile the following method,

The compiler would not know whether the input argument ‘reference’ is of type “A” or type “B”. This must be determined during runtime whether to call method #3 or method #4 depending on what type of object (i.e. instance of Class A or instance of Class B) is assigned to input variable “reference”.

Generics (aka type checking): This happens at compile-time. The compiler checks for the type correctness of the program and translates or rewrites the code that uses generics into non-generic code that can be executed in the current JVM. This technique is known as “type erasure”. In other words, the compiler erases all generic type information contained within the angle brackets to achieve backward compatibility with JRE 1.4.0 or earlier editions.

after compilation becomes:

Annotations: You can have either run-time or compile-time annotations.

@Override is a simple compile-time annotation to catch little mistakes like typing tostring( ) instead of toString( ) in a subclass. User defined annotations can be processed at compile-time using the Annotation Processing Tool (APT) that comes with Java 5. In Java 6, this is included as part of the compiler itself.

@Test is an annotation that JUnit framework uses at runtime with the help of reflection to determine which method(s) to execute within a test class.

The above test fails if it takes more than 100ms to execute at runtime.

The above code fails if it does not throw IndexOutOfBoundsException or if it throws a different exception at runtime. User defined annotations can be processed at runtime using the new AnnotatedElement and “Annotation” element interfaces added to the Java reflection API.

Exceptions: You can have either runtime or compile-time exceptions.

RuntimeException is also known as the unchecked exception indicating not required to be checked by the compiler. RuntimeException is the superclass of those exceptions that can be thrown during the execution of a program within the JVM. A method is not required to declare in its throws clause any subclasses of RuntimeException that might be thrown during the execution of a method but not caught.

Example: NullPointerException, ArrayIndexOutOfBoundsException, etc

Checked exceptions are verified by the compiler at compile-time that a program contains handlers like throws clause or try{} catch{} blocks for handling the checked exceptions, by analyzing which checked exceptions can result from execution of a method or constructor.

Aspect Oriented Programming (AOP): Aspects can be weaved at compile-time, post-compile time, load-time or  runtime.

  • Compile-time:  weaving is the simplest approach. When you have the source code for an application, the AOP compiler (e.g. ajc – AspectJ Compiler)  will compile from source and produce woven class files as output. The invocation of the weaver is integral to the AOP compilation process. The aspects themselves may be in source or binary form. If the aspects are required for the affected classes to compile, then you must weave at compile-time. ? 

  • Post-compile: weaving is also sometimes called binary weaving, and is used to weave existing class files and JAR files. As with compile-time weaving, the aspects used for weaving may be in source or binary form, and may themselves be woven by aspects.?  

  • Load-time: weaving is simply binary weaving deferred until the point that a class loader loads a class file and defines the class to the JVM. To support this, one or more “weaving class loaders”, either provided explicitly by the run-time environment or enabled through a “weaving agent” are required.    

  • Runtime: weaving of classes that have already been loaded  to the JVM.

Inheritance –  happens at compile-time, hence is static.
Delegation or composition – happens at run-time, hence is dynamic and more flexible.

Q4. Have you heard the term “composition should be favored over inheritance“? If yes, what do you understand by this phrase?
A4. Inheritance is a polymorphic tool and is not a code reuse tool. Some developers tend to use inheritance for code reuse when there is no polymorphic relationship. The guide is that inheritance should be only used when a subclass ‘is a’ super class.

  • Don’t use inheritance just to get code reuse. If there is no ‘is a’ relationship then use composition for code reuse. Overuse of implementation inheritance (uses the “extends” key word) can break all the subclasses, if the super class is modified. This is due to tight coupling occurring between the parent and the child classes happening at compile time.
  • Do not use inheritance just to get polymorphism. If there is no ‘is a’ relationship and all you want is polymorphism then use interface inheritance with composition, which gives you code reuse and runtime flexibility.

This is the reason why the GoF (Gang of Four) design patterns favor composition over inheritance. The interviewer will be looking for the key terms — “coupling“, “static versus dynamic” and  “happens at compile-time vs runtime” in your answers. The runtime flexibility is achieved in composition as the classes can be composed dynamically at runtime either conditionally based on an outcome or unconditionally.

Whereas an inheritance is static, as Java does not allow this natively. There are a number of projects and technologies available that will enable you to modify the byte code of a class after compilation, but they really aren’t intended to use for runtime inheritance.

Q5. Can you differentiate compile-time inheritance and runtime delegation/composition with examples and specify which Java supports?

The term “inheritance” refers to a situation where behaviors and attributes are passed on from one object to another. The Java programming language natively only supports compile-time inheritance through subclassing as shown below with the keyword “extends”.

A call to saySomething( ) method on the class “Child” will return “Parent is called, Child is called” because the Child class inherits “Parent is called” from the class Parent. The keyword “super” is used to call the method on the “Parent” class. Runtime inheritance refers to the ability to construct the parent/child hierarchy at runtime. Java does not natively support runtime inheritance, but there is an alternative concept known as “delegation” or “composition”, which refers to constructing a hierarchy of object instances at runtime. This allows you to simulate runtime inheritance. In Java, delegation/composition is typically achieved as shown below:

The Child class delegates the call to the Parent class. Composition can be achieved as follows:

300+ Core Java Interview Q&As
Module 1 Java Overview-
Unit 1 17 Java Overview Interview Q&As  - Preview
Unit 2 4 Java Compile-time Vs Runtime Interview Q&As  - Preview
Module 2 Java data types+
Unit 1 8 Java data types interview Q&As  - Preview
Unit 2 7 Java primitives & objects memory consumption Q&As  - Preview
Unit 3 4 Java autoboxing & unboxing interview Q&As  - Preview
Unit 4 12 Java String class Interview Q&As  - Preview
Module 3 Java modifiers, annotations, initializers & constructors+
Unit 1 6 Java Modifiers every interviewer seems to like  - Preview
Unit 2 10 Java initializers, constructors, regular methods and static factory methods Q&As
Unit 3 8 Java Annotations interview Q&As
Unit 4 4 Java annotation types & processing interview Q&As
Module 4 Java classes, interfaces & class loaders+
Unit 1 12 Java classes and interfaces interview Q&As
Unit 2 3 Abstract classes Vs interfaces interview Q&As
Unit 3 3 Java class loading interview Q&As to ascertain your depth of Java knowledge
Module 5 Java Objects Interview Q&As+
Unit 1 5 Java Object class methods interview Q&As  - Preview
Unit 2 3 Object wait( ) & notify( ) interview Q&As
Unit 3 7 Object equals Vs == and pass by reference Vs value interview Q&As
Unit 4 10 Java immutable objects interview Q&As
Unit 5 10 Java serialization, cloning, and casting interview Q&As
Module 6 OOP & FP+
Unit 1 10 Java OOP Interview Q&As
Unit 2 5 Inheritance Vs Composition OOP Interview Q&As  - Preview
Unit 3 2 Polymorphism OOP Interview Q&As
Unit 4 8 OOP Design principles interview Q&As
Unit 5 5 OOP Vs FP, FP concepts & where to use FP Q&As  - Preview
Unit 6 19 Java Functional Programming (i.e. FP) interview Q&As
Unit 7 Java FP Lambda expressions by examples
Module 7 Generics & Java Collection Framework(JCF)+
Unit 1 12 Java Generics Interview Q&As  - Preview
Unit 2 5 Java Generics Wildcards Interview Q&As
Unit 3 17 Java Collection Framework (JCF) interview Q&As
Unit 4 9 Java data structures interview Q&As
Unit 5 4 Sorting objects in a Collection interview Q&As
Unit 6 8 Java Map interface & Caching interview Q&As
Unit 7 Lambda expressions to work with Java 8 Collections
Module 8 Java multithreading+
Unit 1 17 Java multi-threading interview Q&As  - Preview
Unit 2 7 Java locks & synchronized keyword interview Q&As
Unit 3 9 blocking, scheduling & daemon threads interview Q&As
Unit 4 7 Java Executor framework Interview Q&As
Unit 5 ExecutorService Vs Fork/Join & Future Vs CompletableFuture Interview Q&As
Unit 6 7 Java ThreadLocal interview Q&As
Unit 7 Java Thread stop, resume, suspend & interrupt interview Q&As
Unit 8 12 Java multi-threading differences between X and Y Q&As
Unit 9 Java multi-threading 15 scenarios interview Q&As
Module 9 What is wrong with this multithread code?+
Unit 1 5 Ways to debug Java thread-safety issues  - Preview
Unit 2 Heap Vs Stack, Thread safety & Synchronization  - Preview
Unit 3 Deep Vs Shallow comparison & multithreading
Unit 4 An excellent written test multithreading question - wait/notify
Unit 5 Multithreading & Locks
Unit 6 Java Collection & ConcurrentModificationException
Unit 7 HashMap & Race condition
Unit 8 ConcurrentHashMap & Atomic operations
Unit 9 JConsole for debugging deadlocks in Java
Unit 10 jvisualvm to debug deadlocks in Java
Module 10 Exceptions Handling+
Unit 1 5 Java exception handling interview Q&As
Module 11 Java I/O & NIO+
Unit 1 15 Java old I/O and NIO (i.e. New I/O) interview Q&As
Unit 2 Java 8 way to reading files
Module 12 JVM+
Unit 1 11 JVM memory model and Atomicity, Visibility, and Ordering interview Q&As
Unit 2 8 Java Garbage Collection interview Q&As to ascertain your depth of Java knowledge
Unit 3 jvisualvm to sample Java heap memory
Unit 4 5 JMX and MBean interview Q&As
Module 13 What is new?+
Unit 1 Java 7 features list
Unit 2 Java 8 features list
Module 14 Java code quality+
Unit 1 How will you go about improving on the following Java code?
Unit 2 How will you go about ensuring code quality in Java apps?
Unit 3 5 Java unit testing interview Q&As
Unit 4 Mocks, stubs, domain, and anemic objects interview Q&As
Unit 5 30+ Java Code Review Checklist Items
Module 15 Debugging Java applications+
Unit 1 7 debugging Java interview questions & answers
Unit 2 Debugging "NoSuchMethodError" in Java
Unit 3 Debugging JAR hell issues in Java
Unit 4 Debugging Java version issues
Unit 5 Remote debugging in Java with Java Debug Wire Protocol (JDWP)
Unit 6 Debugging like a pro with eclipse IDE tutorial for Java developers
Module 16 Performance considerations & memory management+
Unit 1 4 Java application performance considerations interview Q&As
Unit 2 8 Java memory management interview Q&As
Unit 3 jvisualvm to detect memory leak
Module 17 Design Patterns Interview Q&As+
Unit 1 12 Java design patterns interview Q&As
Unit 2 5 Java singleton design pattern interview Q&As
Unit 3 Java Proxy, Decorator, Adapter, Bridge, and Facade design patterns Interview Q&As
Unit 4 3 Flyweight design pattern Interview Q&As to improve memory usage & performance
Learn by categories on the go...
Learn by categories such as FAQs – Core Java, Key Area – Low Latency, Core Java – Java 8, JEE – Microservices, Big Data – NoSQL, Architecture – Distributed, Big Data – Spark, etc. Some posts belong to multiple categories.