Reflection
Interview Questions
runtime
.java.lang.Class
class provides various methods that can be used to get metadata, examine and change the runtime behavior of a class.The java.lang.Class class performs mainly two tasks:
There are three ways to instantiate the Class class.
forName()
method of Class class: The forName() method is used to load the class dynamically. It returns the instance of Class class. It should be used if you know the fully qualified name of the class. This cannot be used for primitive types.
getClass()
method of Object class: It returns the instance of Class class. It should be used if you know the type. Moreover, it can be used with primitives.
the .class
syntax: If a type is available, but there is no instance then it is possible to obtain a Class by appending “.class” to the name of the type. It can be used for primitive data type also.
1)forName() method of Class class
- It is used to load the class dynamically.
- It returns the instance of Class class.
- It should be used if you know the fully qualified name of class.
- It cannot be used for primitive types.
public class S {
}
public class STest {
public static void main(String args[]) {
try {
Class c = Class.forName("S");
System.out.println(c.getName());
}catch (Exception e){
System.out.println(e);
}
}
}
S
2) getClass() method of Object class
It returns the instance of Class class.
It should be used if you know the type. Moreover, it can be used with primitives.
public class S {
}
public class STest {
void printName(Object obj){
Class c = obj.getClass();
System.out.println(c.getName());
}
public static void main(String args[]) {
S s = new S();
STest t = new STest();
t.printName(s);
}
}
S
3)The .class syntax
If a type is available, but there is no instance, then it is possible to obtain a Class by appending “.class” to the name of the type. It can be used for primitive data types also.
public class STest {
public static void main(String[] args) {
Class c1 = boolean.class;
System.out.println(c1.getName());
Class c2 = STest.class;
System.out.println(c2.getName());
}
}
boolean
STest
The javap command disassembles a class file.
The javap command displays information about the fields, constructors and methods present in a class file.
Syntax
javap fully_class_name
The following methods of Class class are used to determine the class object:
class Simple{}
interface My{}
class Test{
public static void main(String args[]){
try{
Class c=Class.forName("Simple");
System.out.println(c.isInterface());
Class c2=Class.forName("My");
ZSystem.out.println(c2.isInterface());
}catch(Exception e){
System.out.println(e);}
}
}
false
true
Pros:
Cons:
Yes, by changing the runtime behavior of a class if the class is not secured.
With the help of java.lang.Class
class and java.lang.reflect
.Method class, we can call a private method from any other class.
Required methods of Method class
public void setAccessible(boolean status) throws SecurityException sets the accessibility of the method.
public Object invoke(Object method, Object… args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException is used to invoke the method.
Required method of Class class
public Method getDeclaredMethod(String name,Class[] parameterTypes)throwsNoSuchMethodException,SecurityException: returns a Method object that reflects the specified declared method of the class or interface represented by this Class object.
calling
private method
from another class
public class A {
private void message(){System.out.println("hello java"); }
}
import java.lang.reflect.Method;
public class MethodCall{
public static void main(String[] args)throws Exception{
Class c = Class.forName("A");
Object o= c.newInstance();
Method m =c.getDeclaredMethod("message", null);
m.setAccessible(true);
m.invoke(o, null);
}
}
hello java
call
parameterized private method
from another class
class A{
private void cube(int n){System.out.println(n*n*n);}
}
import java.lang.reflect.*;
class M{
public static void main(String args[])throws Exception{
Class c=A.class;
Object obj=c.newInstance();
Method m=c.getDeclaredMethod("cube",new Class[]{int.class});
m.setAccessible(true);
m.invoke(obj,4);
}
}
64
Accessing
Private Constructors
of a class
- Constructors of a class are a special kind of method this is used to instantiate the class.
- To access the private constructor, we use the method getDeclaredConstructor().
- The getDeclaredConstructor() is used to access a parameterless as well as a parametrized constructor of a class.
class Vehicle {
// private fields of the class Vehicle
private Integer vId;
private String vName;
// parameterless constructor
private Vehicle() {}
// parameterized constructor
private Vehicle(Integer vId, String vName) {
this.vId = vId;
this.vName = vName;
}
// setter methods of the class Vehicle
public void setVehicleId(Integer vId) {
this.vId = vId;
}
public void setVehicleName(String vName) {
this.vName = vName;
}
// getter methods of the class Vehicle
public Integer getVehicleId() {
return vId;
}
public String getVehicleName() {
return vName;
}
}
mport java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
/**
* @author: Amy
* @create: 2023-01-19 16:58
**/
public class PvtConstructorDemo {
// the createObj() method is used to create an object of the Vehicle class using the parameterless constructor.
public void craeteObj(int vId, String vName) throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
// using the parametereless contructor
Constructor<Vehicle> constt = Vehicle.class.getDeclaredConstructor();
constt.setAccessible(true);
Object obj = constt.newInstance();
if (obj instanceof Vehicle)
{
Vehicle v = (Vehicle)obj;
v.setVehicleId(vId);
v.setVehicleName(vName);
System.out.println("Vehicle Id: " + v.getVehicleId());
System.out.println("Vehicle Name: " + v.getVehicleName());
}
}
// the craeteObjByConstructorName() method is used to create an object of the Vehicle class using the parameterized constructor.
public void craeteObjByConstructorName(int vId, String vName) throws NoSuchMethodException, SecurityException,
InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException
{
// using the parameterized contructor
Constructor<Vehicle> constt = Vehicle.class.getDeclaredConstructor(Integer.class, String.class);
if (Modifier.isPrivate(constt.getModifiers()))
{
constt.setAccessible(true);
Object obj = constt.newInstance(vId, vName);
if(obj instanceof Vehicle)
{
Vehicle v = (Vehicle)obj;
System.out.println("Vehicle Id: " + v.getVehicleId());
System.out.println("Vehicle Name: " + v.getVehicleName());
}
}
}
// delegating the responsibility to Java Virtual Machine (JVM) to handle the raised
// exception
// main method
public static void main(String argvs[]) throws InstantiationException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException,
NoSuchMethodException, SecurityException
{
// creating an object of the class PvtConstructorDemo
PvtConstructorDemo ob = new PvtConstructorDemo();
ob.craeteObj(20, "Indica");
System.out.println(" -------------------------- ");
ob.craeteObjByConstructorName(30, "Alto");
}
}
Vehicle Id: 20
Vehicle Name: Indica
--------------------------
Vehicle Id: 30
Vehicle Name: Alto
Miscellaneous
Interview Questions
Wrapper classes
are classes that allow primitive types
to be accessed as objects
.autoboxing
, and the process of converting objects to primitives is called unboxing
.java.lang package
is given below.Primitive Type | Wrapper class |
---|---|
boolean | Boolean |
char | Character |
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
autoboxing
is the process of converting primitive data type to the corresponding wrapper class object, eg., int to Integer.unboxing
is the process of converting wrapper class object to primitive data type. For eg., integer to int.It can occur whenever a wrapper class object is expected, and primitive data type is provided or vice versa.
java.lang.Cloneable interface
must be implemented by the class whose object clone we want to create.protected Object clone() throws CloneNotSupportedException
Department
public class Department {
private int DepartId;
private String DepartName;
public Department(int departId, String departName) {
DepartId = departId;
DepartName = departName;
}
public int getDepartId() {
return DepartId;
}
public void setDepartId(int departId) {
DepartId = departId;
}
public String getDepartName() {
return DepartName;
}
public void setDepartName(String departName) {
DepartName = departName;
}
}
Employee
public class Employee implements Cloneable{
private int id;
private String name;
private Department departemnt;
public Employee(int id, String name, Department departemnt) {
this.id = id;
this.name = name;
this.departemnt = departemnt;
}
//clone
@Override
protected Object clone() throws CloneNotSupportedException{
return super.clone();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Department getDepartemnt() {
return departemnt;
}
public void setDepartemnt(Department departemnt) {
this.departemnt = departemnt;
}
public class Test2 {
public static void main(String[] args) throws CloneNotSupportedException {
Department dept= new Department(1, "HR");
Employee original = new Employee(1, "Admin", dept);
//创建一个原始对象的克隆
Employee cloned = (Employee) original.clone();
//如果克隆确实有效,使用员工ID进行验证
System.out.println(cloned.getId());//1
//验证JDK的规则
// 必须为真且对象必须有不同的内存地址
System.out.println(original != cloned);//true
//返回如果是同一个类为ture
System.out.println(original.getClass() == cloned.getClass());//true
//默认equals方法检查引用,因此它应该是 false,
System.out.println(original.equals(cloned));//false
//说明有两个同一个对象的引用
System.out.println("-------------------------------");
//修改部门名称
cloned.getDepartemnt().setDepartName("Finance");
//查看元数据和clone后的数据是否发生改变,如果两者数据相同,说明引用的是同一个对象
//如果在数据中clone,对clone的数据修改,元数据也会被修改,说明是浅拷贝
//clone的数据修改,元数据也会被修改,这不是我们愿意看到的,我们想要对clone数据修改不影响元数据,这就是深拷贝
System.out.println(original.getDepartemnt().getDepartName());
System.out.println(cloned.getDepartemnt().getDepartName());
}
}
1
true
true
false
-------------------------------
Finance
Finance