GTU Object Oriented Programming - I (Java) Summer 2022 PYQ with solutions

Download Question Paper : click here

Question 1

A. List out features of Java. Explain any two features.

Features of Java.

  • Platform independence
  • Object-oriented programming
  • Automatic memory management (garbage collection)
  • Multi-threading
  • Exception handling
  • Security
  • High performance
  • Dynamic binding
  • Robustness
  • Portability
  • Interpreted
  • Distributed computing
  • Simple and familiar syntax

Two important features of Java are:

  • Platform independence: Java is a platform-independent language, which means that Java code can be written once and run on multiple platforms without the need for recompilation. This is achieved through the use of the Java Virtual Machine (JVM).The JVM interprets the Java bytecode and translates it into machine-specific code at runtime, making it possible to run the same Java code on any platform that has a JVM installed.
  • Object-oriented programming: Java is an object-oriented programming (OOP) language. An object is an instance of a class, which defines the properties and behavior of the object. Java supports encapsulation, inheritance, and polymorphism, which are the three fundamental principles of OOP.

B. Write a single program which demonstrates the usage of following keywords: i. import, ii. new, iii. this, iv. break, v. continue Show how to compile and run the program in java.

import java.util.Scanner;
public class Example {
    private int number;
    public Example(int number) {
        this.number = number;
    }
    public void printNumbers() {
        for (int i = 0; i < number; i++) {
            if (i == 3) {
                break;
            }
            if (i == 1) {
                continue;
            }
            System.out.println(i);
        }
    }
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("Enter a number: ");
        int number = scanner.nextInt();
        Example example = new Example(number);
        example.printNumbers();
    }
}

Import: Import is used to extend and use the functionality of other packages and programs into our program. Usually it is used to Inherit other classes from other packages.

New: New is used to create a new object from a class and store it in memory.

this: this keyword in java used to access the properties and functions of the calling object. It refers to the calling object.

break: break; statement is used to break out of loop anytime we need the condition is fulfilled. It is used to partially run loop based on our requirements.

continue : continue; statement is used to skip an iteration of loop based on certain condition we need have met.

To compile and run this program in Java, follow these steps:

  1. Save the code above in a file named Example.java.
  2. Open a command prompt or terminal window and navigate to the directory where you saved the file.
  3. Compile the program by running the command javac Example.java.
  4. Run the program by running the command java Example.

C. Demonstrate use of try-catch construct in case of hierarchical

Exception Handling. (i.e. handling various exception belongs to the exception hierarchy)

Here is an example Java program that demonstrates the use of try-catch construct in hierarchical exception handling:

import java.io.*;
import java.sql.*;

public class ExceptionDemo {
   public static void main(String[] args) {
      try {
         // some code that may throw an exception
         throw new SQLException(); // for demonstration purposes only
      } catch (IOException e) {
         System.out.println("Caught an IOException: " + e.getMessage());
      } catch (SQLException e) {
         System.out.println("Caught an SQLException: " + e.getMessage());
      } catch (Exception e) {
         System.out.println("Caught some other exception: " + e.getMessage());
      }
   }
}
  • Handling various exceptions requires multiple catch statements sequentially.
  • One thing to keep in mind while handling various hierarchical exception is to not make code unreachable. i.e. for example if we place ‘Exception’ class above the class that have been derived from Exception class will make to derived class catch blocks unreachable.
  • So always keep the Super class catch block at last will prevent Unreachable code.
  • Another way to handle various Exception classes in by using ‘Nested Try catch blocks.
import java.io.*;
import java.sql.*;

public class ExceptionDemo {
   public static void main(String[] args) {
      try {
         try {
            // some code that may throw an exception
            throw new SQLException(); // for demonstration purposes only
         } catch (IOException e) {
            System.out.println("Caught an IOException: " + e.getMessage());
         }
      } catch (SQLException e) {
         System.out.println("Caught an SQLException: " + e.getMessage());
      } catch (Exception e) {
         System.out.println("Caught some other exception: " + e.getMessage());
      }
   }
}

Question 2

A. Explain following Java keywords using appropriate examples:i) static, ii) final, iii) super.

  • static:
    In Java, static is a keyword used to create class-level variables or methods that can be accessed without creating an instance of the class. When a variable or method is declared as static, it belongs to the class and not to any individual instance of the class. static variables are shared by all the instances of class.
    java public class MyClass { static int myVar = 42; public static void main(String[] args) { System.out.println(myVar); } }
  • final keyword:
    The final keyword in Java is used to create a constant variable, which means its value cannot be changed once it has been initialized. You can declare a variable, method, or class as final.
    java public class MyClass { final int myVar = 42; public static void main(String[] args) { MyClass obj = new MyClass(); System.out.println(obj.myVar); } }
  • super keyword:
    The super keyword in Java is used to refer to the parent class of a subclass. You can use it to call the constructor or method of the parent class.
    java public class ParentClass { int x; public ParentClass(int x) { this.x = x; } } public class ChildClass extends ParentClass { int y; public ChildClass(int x, int y) { super(x); this.y = y; } }

B. Consider class A as the parent of class B. Explain among the

following which statement will show the compilation error. i) A a = new A(); ii) A a = new B(); iii) B b = new A(); iv) B b = new B();

  • In this scenario, class A is the parent class of class B. Here are the explanations for each statement:
    1. A a = new A(); This statement creates an instance of class A and assigns it to a variable of type A. Since this statement is creating an object of the same class as the variable type, there will be no compilation error.
    2. A a = new B(); This statement creates an instance of class B and assigns it to a variable of type A. Since class B is a subclass of class A, this statement is valid and there will be no compilation error.
    3. B b = new A(); This statement creates an instance of class A and assigns it to a variable of type B. Since class A is the parent class of class B, this statement is invalid and will result in a compilation error.
    4. B b = new B(); This statement creates an instance of class B and assigns it to a variable of type B. Since this statement is creating an object of the same class as the variable type, there will be no compilation error.

Therefore, the statement that will show a compilation error is iii) B b = new A();

C. Write a java program to take infix expressions and convert it into

prefix expressions.

import java.util.Arrays;

public class InfixToPrefix {

    public static void main(String[] args) {
        String infixExp = "5 * ( 4 + 3 ) - 2 / 1";
        String prefixExp = infixToPrefix(infixExp);
        System.out.println("Infix expression: " + infixExp);
        System.out.println("Prefix expression: " + prefixExp);
    }

    public static String infixToPrefix(String infixExp) {
        char[] stack = new char[infixExp.length()];
        int top = -1;
        StringBuilder prefixExp = new StringBuilder();

        for (int i = infixExp.length() - 1; i >= 0; i--) {
            char ch = infixExp.charAt(i);

            if (ch == '(') {
                stack[++top] = ')';
            } else if (ch == ')') {
                stack[++top] = '(';
            } else if (Character.isLetterOrDigit(ch)) {
                prefixExp.append(ch);
            } else {
                while (top >= 0 && stack[top] == ')') {
                    prefixExp.append(stack[top--]);
                }
                stack[++top] = ch;
            }
        }

        while (top >= 0) {
            prefixExp.append(stack[top--]);
        }

        return prefixExp.reverse().toString();
    }
}

C. Write a java program that evaluates a math expression given in string

form from command line arguments.

public class MathExpressionEvaluator {

    public static void main(String[] args) {
        if (args.length == 0) {
            System.out.println("Usage: java MathExpressionEvaluator <math_expression>");
            return;
        }

        String expression = args[0];

        try {
            double result = evaluate(expression);
            System.out.println("Result: " + result);
        } catch (IllegalArgumentException e) {
            System.out.println("Invalid expression: " + expression);
        }
    }

    public static double evaluate(String expression) throws IllegalArgumentException {
        String[] operands = expression.split("[+\\-*/]");
        String[] operators = expression.split("\\d+(\\.\\d+)?");

        if (operands.length != operators.length + 1) {
            throw new IllegalArgumentException("Invalid expression");
        }

        double result = Double.parseDouble(operands[0]);

        for (int i = 0; i < operators.length; i++) {
            double operand = Double.parseDouble(operands[i + 1]);
            char operator = operators[i].charAt(0);

            // Evaluate the current operation based on operator precedence
            if (operator == '*' || operator == '/') {
                double previousOperand = Double.parseDouble(operands[i]);
                char previousOperator = operators[i - 1].charAt(0);

                if (previousOperator == '*') {
                    result *= operand;
                } else if (previousOperator == '/') {
                    result /= operand;
                } else {
                    throw new IllegalArgumentException("Invalid expression");
                }
            } else if (operator == '+') {
                result += operand;
            } else if (operator == '-') {
                result -= operand;
            } else {
                throw new IllegalArgumentException("Invalid expression");
            }
        }

        return result;
    }
}

Question 3

A. Define types of Inheritance

  • Inheritance is a mechanism in object-oriented programming that allows a class to inherit properties and methods from another class. There are several types of inheritance in Java:
    1. Single inheritance: A class can inherit from only one superclass. For example:

      class Animal {
         void eat() {
             System.out.println("Animal is eating");
         }
      }
      class Dog extends Animal {
         void bark() {
             System.out.println("Dog is barking");
         }
      }
    2. Multilevel inheritance: A class can inherit from a superclass, and that superclass can also inherit from another superclass. For example:

      class Animal {
         void eat() {
             System.out.println("Animal is eating");
         }
      }
      class Dog extends Animal {
         void bark() {
             System.out.println("Dog is barking");
         }
      }
      class Labrador extends Dog {
         void color() {
             System.out.println("Labrador is brown");
         }
      }
    3. Hierarchical inheritance: Multiple classes can inherit from a single superclass. For example:

      class Animal {
         void eat() {
             System.out.println("Animal is eating");
         }
      }
      class Dog extends Animal {
         void bark() {
             System.out.println("Dog is barking");
         }
      }
      class Cat extends Animal {
         void meow() {
             System.out.println("Cat is meowing");
         }
      }
    4. Multiple inheritance: A class can inherit from multiple superclasses. However, Java does not support multiple inheritance of classes. It only supports multiple inheritance of interfaces, which is achieved through the implements keyword. For example:

      interface Animal {
         void eat();
      }
      
      interface Mammal {
         void giveBirth();
      }
      
      class Platypus implements Animal, Mammal {
         void swim() {
             System.out.println("Platypus is swimming");
         }
         
         public void eat() {
             System.out.println("Platypus is eating");
         }
         
         public void giveBirth() {
             System.out.println("Platypus is giving birth");
         }
      }
    5. Hybrid inheritance: is a combination of multiple types of inheritance. It involves multiple inheritance and hierarchical inheritance at the same time. In other words, it is a combination of two or more types of inheritance.

      class GrandFather {    
         public void showG() {    
             System.out.println("He is grandfather.");    
         }    
      }    
      //inherits GrandFather properties    
      class Father extends GrandFather {    
         public void showF() {    
             System.out.println("He is father.");    
         }    
      }    
      //inherits Father properties    
      class Son extends Father {    
         public void showS() {    
             System.out.println("He is son.");    
         }    
      }    
      //inherits Father properties    
      public class Daughter extends Father {    
         public void showD() {    
             System.out.println("She is daughter.");    
         }       
      }

B. Explain the following constructors using appropriate example:

i) Default constructor and Parameterized constructor ii) Shallow copy and Deep copy constructor.

  1. Default constructor and Parameterized constructor:
    • Default Constructor : A default constructor is a constructor that is provided by the compiler if no other constructor is defined in the class. It is a constructor that takes no arguments and does nothing.

      public class ExampleClass {
         int num;
         ExampleClass() {
             num = 0;
         }
      }
      
      public class Main {
         public static void main(String[] args) {
             ExampleClass obj1 = new ExampleClass(); // Default constructor is called
             System.out.println(obj1.num); // Output: 0
         }
      }
    • Parameterized Constructor : A parameterized constructor is a constructor that takes one or more parameters. It is used to initialize the data members of the class with user-defined values.

      public class ExampleClass {
         int num;
         ExampleClass(int n) {
             num = n;
         }
      }
      
      public class Main {
         public static void main(String[] args) {
             ExampleClass obj2 = new ExampleClass(10);
             System.out.println(obj2.num); // Output: 10
         }
      }
  2. Shallow copy and Deep copy constructor :
    • Shallow Copy : A shallow copy constructor creates a new object that shares the same data members with the original object. Changes made to the data members of one object will also affect the other object.

      public class ExampleClass {
         int[] arr;
         ExampleClass(int[] a) {
             arr = a;
         }
         // Shallow copy constructor
         ExampleClass(ExampleClass original) {
             arr = original.arr;
         }
      }
      
      public class Main {
         public static void main(String[] args) {
             int[] a = {1, 2, 3};
             ExampleClass obj1 = new ExampleClass(a);
             ExampleClass obj2 = new ExampleClass(obj1); // Shallow copy
             obj2.arr[0] = 5;
             System.out.println(obj1.arr[0]); // Output: 5
         }
      }
    • Deep Copy Constructor : A deep copy constructor creates a new object that has its own copy of the data members of the original object. Changes made to the data members of one object will not affect the other object.

      public class ExampleClass {
         int[] arr;
         ExampleClass(int[] a) {
             arr = a;
         }
         // Deep copy constructor
         ExampleClass(ExampleClass original) {
             arr = new int[original.arr.length];
             for (int i = 0; i < original.arr.length; i++) {
                 arr[i] = original.arr[i];
             }
         }
      }
      public class Main {
         public static void main(String[] args) {
             int[] a = {1, 2, 3};
             ExampleClass obj1 = new ExampleClass(a);
             ExampleClass obj2 = new ExampleClass(obj1); // Deep copy
             obj2.arr[0] = 5;
             System.out.println(obj1.arr[0]); // Output: 1
         }
      }

C. Explain file io using byte stream with appropriate example.

hint: use FileInputStream, FileOutputStream.

  • File I/O using byte stream in Java involves reading or writing binary data from or to a file. The byte stream classes in Java are FileInputStream and FileOutputStream.
  • FileInputStream class is used to read data from a file as bytes, and FileOutputStream class is used to write data to a file as bytes.
  • Here is an example of how to use FileInputStream and FileOutputStream to read from and write to a file in Java:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileIOExample {

    public static void main(String[] args) {
        FileInputStream inputStream = null;
        FileOutputStream outputStream = null;

        try {
            // Input file
            inputStream = new FileInputStream("input.txt");

            // Output file
            outputStream = new FileOutputStream("output.txt");

            byte[] buffer = new byte[1024];
            int bytesRead;

            // Read from the input file and write to the output file
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // Close the input and output streams
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}

Question 3

A. Define types of polymorphism

  • Polymorphism is the ability of an object to take on many forms.
  • Polymorphism allows us to perform a single action in different ways.
  • The word “poly” means many and “morphs” means forms.

In Java polymorphism is mainly divided into two types:

  1. Compile-time Polymorphism
    • It is also known as static polymorphism. This type of polymorphism is achieved by function overloading or operator overloading.
public class MathUtils {
    public int add(int x, int y) {
        return x + y;
    }
    
    public double add(double x, double y) {
        return x + y;
    }
}
  1. Runtime Polymorphism
    • This type of polymorphism is also known as method overriding. In method overriding, a subclass provides a specific implementation of a method that is already provided by its parent class.
    • The implementation in the subclass overrides (replaces) the implementation in the parent class.
public class Animal {
    public void makeSound() {
        System.out.println("The animal makes a sound");
    }
}

public class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("The dog barks");
    }
}

B. Explain the Following

  1. Arguments and Parameters of a function
    • Argument: An argument is a value passed to a function when the function is called. Whenever any function is called during the execution of the program there are some values passed with the function. These values are called arguments.
public class Example {
    public static int multiply(int a, int b) {
        return a * b;
    }
    public static void main(String[] args) {
        int x = 2;
        int y = 5;

        // the variables x and y are arguments
        int product = multiply(x, y);

        System.out.println("PRODUCT IS: " + product);
    }
}
  • Parameter: A parameter is a variable used to define a particular value during a function definition. Whenever we define a function we introduce our compiler with some variables that are being used in the running of that function. These variables are often termed as Parameter.
public class Example {

    // the variables a and b are parameters
    public static int multiply(int a, int b) {
        return a * b;
    }

    public static void main(String[] args) {
        int x = 2;
        int y = 5;
        int product = multiply(x, y);
        System.out.println("PRODUCT IS:" + product);
    }
}
  1. Pass by Value and Pass by reference
    • Pass By Value
      • In Pass by value, function is called by directly passing the value of the variable as an argument. So any changes made inside the function does not affect the original value.
      • In Pass by value, parameters passed as an arguments create its own copy. So any changes made inside the function is made to the copied value not to the original value .
public class Example {
    public static void main(String[] args) {
        int x = 10;
        System.out.println("Before calling the method: " + x);
        changeValue(x);
        System.out.println("After calling the method: " + x);
    }

    public static void changeValue(int x) {
        x = 20;
        System.out.println("Inside the method: " + x);
    }
}
  • Pass by Reference
    • In Pass by Reference, Function is called by directly passing the reference/address of the variable as an argument. So changing the value inside the function also change the original value.
    • In Pass by reference, parameters passed as an arguments does not create its own copy, it refers to the original value so changes made inside function affect the original value.
public class PassByReferenceExample {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        System.out.println("Before modifyArray function call: " + arr[0]);
        modifyArray(arr);
        System.out.println("After modifyArray function call: " + arr[0]);
    }
    public static void modifyArray(int[] arr) {
        arr[0] = 5;
    }
}

C. Explain file io using character stream with appropriate example.

hint: use FileReader, FileWriter.

  • File I/O using character stream in Java involves reading or writing data from or to a file as characters. The character stream classes in Java are FileReader and FileWriter.
  • FileReader class is used to read data from a file as characters, and FileWriter class is used to write data to a file as characters.
  • Example of how to use FileReader and FileWriter to read from and write to a file as characters in Java:
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class FileIOExample {

    public static void main(String[] args) {
        FileReader reader = null;
        FileWriter writer = null;

        try {
            // Input file
            reader = new FileReader("input.txt");
            // Output file
            writer = new FileWriter("output.txt");
            int character;
            // Read from the input file and write to the output file
            while ((character = reader.read()) != -1) {
                writer.write(character);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // Close the input and output streams
            try {
                if (reader != null) {
                    reader.close();
                }
                if (writer != null) {
                    writer.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}

Question 4

A. Define Encapsulation and Access Specifier.

  • Encapsulation is one of the fundamental principles of object-oriented programming, and it refers to the practice of binding data and behavior together within a single unit, called a class.
  • In Java, encapsulation is achieved by declaring the class fields (variables) as private, and providing public methods (also called getters and setters) to access and modify those fields.
  • Access specifiers in Java are keywords used to define the visibility or accessibility of class members (fields, methods, and inner classes) from other parts of the program. Java has four access specifiers:
    1. Public: A public class member is accessible from anywhere in the program, both inside and outside the package.
    2. Private: A private class member is accessible only within the class in which it is declared.
    3. Protected: A protected class member is accessible within the same package, and also in any subclass of the class in which it is declared.
    4. Default (also known as package-private): A default class member is accessible only within the same package.
  • By using access specifiers in Java, we can control the visibility of our class members and ensure that they are accessed and modified only in the appropriate ways. This helps to ensure the integrity and security of our code, and can make it easier to maintain and extend our programs over time.

B. Explain MultiThreading using Thread class.

  • Multithreading allows for concurrent execution of two or more parts of a program. Each part of a program that can be executed concurrently is called a thread. The Thread class in Java provides a way to create and manage threads.
  • Multithreading in java can be implemented in two ways:
    • Extending Thread class
    • Implementing Runnable Interface
  • To Implement Multithreading using Thread class:
    • Extend the Thread class and Implement run() method.

      public class MyThread extends Thread {
        public void run() {
            // code to be executed in this thread
        }
      }
    • Make and instance of Thread class and call start() method.

      MyThread thread = new MyThread();
      thread.start();
  • Multithreading helps in concurrent execution of small parts of program which increases the efficiency of program.

C. Write a Short note on Java Collections.

  • Java Collections is a framework that provides a set of classes and interfaces to represent and manipulate groups of objects. It offers a wide range of data structures such as lists, sets, maps, queues, and more, that are highly optimized and easy to use. Here are some key features and benefits of Java Collections:
    1. Dynamic resizing: Collections in Java automatically resize themselves as new elements are added or removed. This makes it easy to add or remove elements from a collection without worrying about managing the underlying data structure.
    2. Type safety: Collections in Java are type-safe, which means that the compiler ensures that you can only add elements of the correct type to a collection. This helps to prevent runtime errors and improve code reliability.
    3. Iteration: Java Collections provides a range of methods to iterate over the elements in a collection, including the enhanced for-loop and the Iterator interface.
    4. Sorting and searching: Collections in Java support various sorting and searching algorithms, making it easy to sort and search through large collections of data.
    5. Thread-safety: Many collection classes in Java are thread-safe, which means they can be used in a multi-threaded environment without worrying about synchronization issues.
    6. High-performance: Java Collections are designed to be highly optimized for performance, with algorithms and data structures that are carefully tuned to maximize efficiency.
    7. Extensibility: Java Collections can be extended and customized to meet the specific needs of an application. For example, you can create your own collection classes that implement specific interfaces or use custom data structures.
  • Overall, Java Collections provides a powerful and flexible framework for working with groups of objects in Java, making it easier to write efficient, reliable, and scalable code.

Question 4

A. Differentiate between Abstract class and Interfaces.

Abstract ClassesInterfaces
Can have abstract and non-abstract methodsCan only have abstract methods
Can have a constructorCannot have a constructor
Can extend one abstract classCan implement multiple interfaces
Can have any access modifierMethods are always public by default
Can have instance variablesCannot have instance variables
Used for defining base classes with common functionalityUsed for defining a set of behaviors that a class must implement

B. Explain Multithreading using Runnable Interface.

  • Multithreading allows for concurrent execution of two or more parts of a program. Each part of a program that can be executed concurrently is called a thread. The Thread class in Java provides a way to create and manage threads.
  • To Implement MultiThreading using ‘Runnable’ Interface:
    • Implement the Runnable Interface into a class.

      public class MyRunnable implements Runnable {
        public void run() {
            // Code to be executed by the thread goes here
        }
      }
    • In the main class create an instance of the class.
    • Pass that instance object as a argument into a Thread class object constructor.
    • call start method of Thread class object.

      public class Main {
        public static void main(String[] args) {
            MyRunnable myRunnable = new MyRunnable();
            Thread thread = new Thread(myRunnable);
            thread.start();
        }
      }

C. Write a program to add input elements in ArrayList collection class,

then sort the inserted elements in descending order and display the sorted output. hint: use Collections.reverseOrder()

import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // Create an ArrayList to store input elements
        ArrayList<Integer> numbers = new ArrayList<>();

        // Prompt the user to enter input elements
        System.out.print("Enter the number of elements: ");
        int count = scanner.nextInt();

        System.out.print("Enter " + count + " elements: ");
        for (int i = 0; i < count; i++) {
            numbers.add(scanner.nextInt());
        }

        // Sort the elements in descending order
        Collections.sort(numbers, Collections.reverseOrder());

        // Display the sorted output
        System.out.print("Sorted Output: ");
        for (int i = 0; i < count; i++) {
            System.out.print(numbers.get(i) + " ");
        }
    }
}

Question 5

A. Explain following Java keywords using appropriate examples:

i) throw, ii) throws, iii) finally

  1. throw : throw is a keyword in Java that is used to explicitly throw an exception from a method or a block of code. The throw keyword is followed by an instance of the Exception class or one of its subclasses. Here's an example:
public class Main {
    public static void main(String[] args) {
        try {
            throw new Exception("Something went wrong!");
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}
  1. throws : is a keyword in Java that is used to declare that a method may throw one or more exceptions. It is used when a method is unable to handle an exception that may occur within its body and needs to signal to the caller that the method may throw an exception. The throws keyword is followed by the name of the exception class or classes that the method may throw. Here's an example:
public class Main {
    public static void main(String[] args) throws Exception {
        throw new Exception("Something went wrong!");
    }
}
  1. finally: finally is a keyword in Java that is used to define a block of code that will be executed regardless of whether an exception is thrown or not. It is typically used to release resources that were acquired within a try block, or to perform cleanup operations. The finally block is always executed, regardless of whether an exception is thrown, caught, or not caught. Here's an example:
public class Main {
    public static void main(String[] args) {
        try {
            // Code that may throw an exception
        } catch (Exception e) {
            // Exception handling code
        } finally {
            // Code that will always be executed
        }
    }
}

B. In multi-threading using Thread class, explain with an example how

a start() method call invokes the run method of the class extending Thread class.

  • Multithreading is used for concurrent running of several parts of program.
  • Multithreading can be done by Extending ‘Thread’ class.
public class MyThread extends Thread {
    public void run() {
        System.out.println("Thread is running.");
    }
}

public class Main {
    public static void main(String[] args) {
        MyThread t = new MyThread();
        t.start();
    }
}
  1. Create a class which extends ‘Thread’ class and implement run() method.
  2. Create an Instance of the class which Extends Thread class.
  3. Invoke start() method from an instance of the extended class.
    • start() method implicitly calls run() method of a class.
    • start() method is responsible for context switch and concurrent execution of the program.
    • If we directly call run() method from an instance then it will execute as a normal function execution, that is sequentially.

C. Write a short note on JAVAFX controls.

  • JavaFX controls are a set of UI components that provide a rich user interface for JavaFX applications. These controls include buttons, labels, text fields, checkboxes, radio buttons, sliders, progress bars, and many more.
  • JavaFX controls are highly customizable, and their appearance and behavior can be easily modified using CSS and event handling. They support both layout constraints and responsive design, making it easy to create user interfaces that adapt to different screen sizes and resolutions.
  • JavaFX controls are built on top of the JavaFX toolkit, which provides a set of APIs for developing rich graphical user interfaces in Java applications. The toolkit also includes a powerful layout manager that can be used to arrange the controls on the screen and handle their resizing and positioning.
  • Some of the key features of JavaFX controls include:
    1. Easy customization: JavaFX controls can be easily customized to match the look and feel of your application using CSS.
    2. Event handling: JavaFX controls support event handling, allowing you to respond to user interactions with the UI.
    3. Layout support: JavaFX controls support layout constraints, making it easy to create complex UI layouts.
    4. Responsive design: JavaFX controls support responsive design, allowing your UI to adapt to different screen sizes and resolutions.
    5. They also support animations, transitions, and effects that can be used to create engaging and dynamic user interfaces.

Question 5

A. Explain thread life cycle

  • A Thread is a lightweight process that executes a set of instructions concurrently with other threads. The life cycle of a thread refers to the stages it goes through from its creation to its termination. The thread life cycle in Java can be divided into the following states:
    1. New: When a thread is created but has not yet started, it is in the new state. In this state, the thread has been allocated memory, but it has not yet begun execution.
    2. Runnable: When the start() method is called on a thread object, it enters the runnable state. In this state, the thread is ready to run, but it has not yet been scheduled to run by the operating system.
    3. Running: When a thread is scheduled to run by the operating system, it enters the running state. In this state, the thread is executing its instructions.
    4. Blocked: A thread can be blocked when it is waiting for a resource to become available or for some other condition to be satisfied. In this state, the thread is not executing any instructions, and it cannot be scheduled to run until the blocking condition is resolved.
    5. Waiting: A thread can enter the waiting state when it waits for another thread to complete its execution or for a certain condition to become true. In this state, the thread is not executing any instructions, and it cannot be scheduled to run until the condition is satisfied.
    6. Terminated: When a thread completes its execution or is terminated due to some exception or error, it enters the terminated state. In this state, the thread is no longer executing, and its resources can be reclaimed by the system.

B. In multi-threads using the Runnable interface, explain with an

example how a start() method calls the run() method of a class implementing a runnable interface.

  • the Runnable interface is used to create a thread by implementing its run() method. When a class implements the Runnable interface and defines the run() method, it can be used to create a new thread using the Thread class.
  • Here's an example of how the start() method calls the run() method of a class implementing the Runnable interface:
public class MyRunnable implements Runnable {
    public void run() {
        // Code to be executed in this thread
        System.out.println("MyRunnable thread is running");
    }
}

public class Main {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread myThread = new Thread(myRunnable);
        myThread.start(); // Starting the thread
    }
}
  • Steps:
    1. Implement the Runnable Interface to the class.
    2. Override the run() method.
    3. Create an Instance of the extended class.
    4. Create an Object of Thread class and pass the instance of extended class as a parameter.
    5. call start() method from thread class object.

C. Develop a GUI based application using JavaFX controls.

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;

public class MyGUIApplication extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        // Create the label, text field, and button
        Label label = new Label("Enter some text:");
        TextField textField = new TextField();
        Button button = new Button("Display");

        // Create the layout
        GridPane gridPane = new GridPane();
        gridPane.setPadding(new Insets(10));
        gridPane.setHgap(10);
        gridPane.setVgap(10);
        gridPane.add(label, 0, 0);
        gridPane.add(textField, 1, 0);
        gridPane.add(button, 1, 1);

        // Create the scene and add the layout to it
        Scene scene = new Scene(gridPane, 300, 100);

        // Set the event handler for the button
        button.setOnAction(event -> {
            String text = textField.getText();
            label.setText("You entered: " + text);
        });

        // Set the stage title and show the stage
        primaryStage.setTitle("My GUI Application");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
  • In this example, we create a simple GUI application using JavaFX controls. We create a label, text field, and button and add them to a GridPane layout. We then create a Scene object and add the layout to it.
  • We also set an event handler for the button that retrieves the text entered in the text field and displays it in the label.
  • Finally, we set the stage title and show the stage by calling the show() method on the Stageobject.