简体   繁体   中英

Override a method of another class using Java Reflections

I have a Java Project where I have 2 classes. I need to use Java reflections to first print the default values as set by the constructor in ProjectAccount.java from mywork.java class and then I need to Override the toString() method to pass values from mywork.java class and print them.

I was able to use java reflections to print the default constructor-set values. But I am getting an error when trying to override and print the toString() method with arguments.

ProjectAccount.java

package relive;

public class ProjectAccount {
    private String projectAccountID;
    private double budget;
    public int noOfProjects;

    public ProjectAccount(){
        this.projectAccountID = "MARTINDAWS-BillAnalyzer-001";
        this.budget = 120000.00;
        this.noOfProjects = 10;
    }

    @Override
    public String toString(){
        return "Project Accoutn ID = " + projectAccountID + " , Project Budget = "+budget + " , No of Projects = "+ noOfProjects;
    }
}

mywork.java

package relive;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class mywork {

    public static void main(String[] args) {
        try{
            Class<?> clazz = Class.forName("relive.ProjectAccount");
            Constructor<?> constr = clazz.getDeclaredConstructor(null);
            Method mets = clazz.getDeclaredMethod("toString", null);
            Object obj = constr.newInstance(new Object[] {});

            //Print Default values
            System.out.println(mets.invoke(obj, null));

            String mod_projectAccountID="ORPT-BT-EMP-DEV";
            double mod_budget = 2200000.0;
            int mod_noOfProjects = 20;

            //Print new passed values using the overridden method
            System.out.println(mets.invoke(obj, mod_projectAccountID,mod_budget, mod_noOfProjects));        
        }

        catch(ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e){
            e.printStackTrace();
        }
    }
    public static String toString(String mod_projectAccountID, double mod_budget, int mod_noOfProjects){
        return "Project Accoutn ID = " + mod_projectAccountID + " , Project Budget = "+mod_budget + " , No of Projects = "+ mod_noOfProjects; 
    }

}

Output and Error

输出

I guess that I am encountering this error since I have not overridden the toString() method yet. Any suggestions on how I could override and print this will be highly appreciated.

there are a few issues in there.

  1. overriding toString is through defining an instance method (yours is static)
  2. your reflective access is with mets ,which references the ProjectAccount class
  3. mywork is not a subclass of ProjectAccount
  4. you can't add parameters,

The ability of a subclass to override a method allows a class to inherit from a superclass whose behavior is "close enough" and then to modify behavior as needed. The overriding method has the same name, number and type of parameters, and return type as the method that it overrides. An overriding method can also return a subtype of the type returned by the overridden method. This subtype is called a covariant return type.

Oracle Docs

package de.me.example;

public class SuperType {

    @Override
    public String toString() {

        return "SuperType";
    }

}


package de.me.example;

public class SubType extends SuperType {

    // this annatotion is syntactic sugar nothing more,
    //it behaves the same without it
    @Override
    public String toString() {
        return "SubType";
    }

}

I just modified the mywork.java class to access the ProjectAccount.java class variables directly and set them.

I accessed the declared fields and based on the name or the type of the variable I modified the declared variables and called the same toString() method without overriding the toString() method.

mywork.java

package relive;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class answer_a {

    public static void main(String[] args) {
        try{
            Class<?> clazz = Class.forName("relive.ProjectAccount");
            Constructor<?> constr = clazz.getDeclaredConstructor(null);
            Method mets = clazz.getDeclaredMethod("toString", null);
            Object obj = constr.newInstance(new Object[] {});

            //Print Default values
            System.out.println(mets.invoke(obj, null));

            String mod_projectAccountID= "ORPT-BT-EMP-DEV";
            double mod_budget = 2200000.0;
            int mod_noOfProjects = 20;

            //Method that accesses the Fields and modifies them with the new variables

            Field [] fields = clazz.getDeclaredFields();
            for(int y=0; y<fields.length; y++){
                fields[y].setAccessible(true);

                if(fields[y].getName() == "projectAccountID"){
                    fields[y].set(obj, mod_projectAccountID);
                }
                else if(fields[y].getType().getSimpleName() == "double"){
                    fields[y].set(obj, mod_budget);
                }
                else if (fields[y].getType().getSimpleName() == "int"){
                    fields[y].set(obj, mod_noOfProjects);
                }
            }

            System.out.println(mets.invoke(obj, null));

        }
        catch(ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e){
            e.printStackTrace();
        }
    }

}

Output

输出

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM