Java: What scenarios call for the use of reflection?

前端 未结 7 1077
无人共我
无人共我 2020-12-29 10:42

So from reading some of the articles, the message i got out of it was being able to modify fields and set values to classes in real time without recompiling.

so is i

相关标签:
7条回答
  • 2020-12-29 11:17

    Here are some cases to use reflection in

    public class Main {
    
        public static void main(String[] args) {
    
            displayProperties(Stage.class);
        }
    
        public static void displayProperties(Class class) {
            boolean hasParam = false;
            boolean hasReturn = false;
            ArrayList<Method> propMethods = new ArrayList<>();
            Method[] methods = clazz.getMethods();
            for (Method m: methods) {
    
                Parameter[] paraType = m.getParameters();
                if(m.getParameterCount()<2) {
                    if ((m.getReturnType() == void.class && paraType.length == 1) || (m.getReturnType() != void.class && paraType.length == 0)) {
                        //Get the properties alone
                        propMethods.add(m);
                    }
                }
    
            }
            for (int i = 0; i < propMethods.size(); i++) {
    
                if (propMethods.get(i).getName().startsWith("get") || propMethods.get(i).getName().startsWith("set")) {
    
                    System.out.println(readWrite(propMethods.get(i), propMethods) + " " + propMethods.get(i).getName().substring(3)+"( "+propMethods.get(i).getReturnType().getTypeName()+" )");
                } else
                    System.out.println(readWrite(propMethods.get(i), propMethods) + " " + propMethods.get(i).getName() + "( "+propMethods.get(i).getReturnType().getTypeName()+" )");
            }
    
        }
    
        public static String readWrite(Method method, ArrayList<Method> propMeths) {
    
            ArrayList<Method> temp;
            temp = propMeths;
    
            boolean readIn = false;
            boolean writeIn = false;
            String onlyName = method.getName().substring(3);
    
            for (int i = 0; i < temp.size(); i++) {
                //use the substring--
    
                if (temp.get(i).getName().startsWith("get") && temp.get(i).getName().endsWith(onlyName)) {
                    readIn = true;
                }
                if (temp.get(i).getName().startsWith("set") && temp.get(i).getName().endsWith(onlyName)) {
    
                    writeIn = true;
                }
            }
    
            if (readIn == true && writeIn == true)
                return "rw ";
            else if (readIn == true && writeIn == false)
                return "r ";
            else
                return "w ";
        }
    }
    

    Another case with the String class

    public static void main(String[] args) 
        {
            displayProperties(String.class);
        }
    
        public static void displayProperties(Class class){
            clazz.getDeclaredFields();
    
            Method[] methods = clazz.getDeclaredMethods();
    
            for(int ii = 0; ii<methods.length; ii++){
                System.out.println("Method Name: "+methods[ii].getName());
                System.out.println("Method Type: "+methods[ii].getReturnType());
                System.out.println("Method Pa: "+methods[ii].getParameterCount());
                System.out.println("Method Type: "+methods[ii].getReturnType());
    
            }
        }
    

    Loading from XML with reflection

    public static Object loadFromXml(String filePath) throws Exception {
    
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            File newFile = new File(filePath);
            Document doc = builder.parse(newFile);
            Node root = doc.getFirstChild();
    
            return loadObjectElement(root);
    
    
        }
        /**
         * This method loads from an xml file and returns all the contents of the file as an object
         * @param root The node passed in to the method from which the "tree" gets a new level
         * @return all the contents of the xml file as an object
         * @throws Exception
         */
        public static Object loadObjectElement(Node root) throws Exception {
            //loads the root
            String studentClass = root.getAttributes().getNamedItem("class").getTextContent();
            Object newStudentObject = Class.forName(studentClass).newInstance();
            //gets the children nodes (may have text elements like \n)
            NodeList studentFieldList = root.getChildNodes();
    
            //iterates through the children nodes
            for (int i = 0; i < studentFieldList.getLength(); i++) {
                //checks to make sure the child node is not a text node
                if (studentFieldList.item(i).getNodeType() != Node.TEXT_NODE) {
                    //checks if the current node does not have children
                    if (studentFieldList.item(i).getChildNodes().getLength() == 0) {
                        //receives data of the current node
                        String nameField = studentFieldList.item(i).getAttributes().getNamedItem("name").getTextContent();
                        String valueField = studentFieldList.item(i).getAttributes().getNamedItem("value").getTextContent();
                        Field declaredFieldInClass = newStudentObject.getClass().getDeclaredField(nameField);
    
                        //makes the field accessible
                        declaredFieldInClass.setAccessible(true);
                        //checks the field type
                        switch (declaredFieldInClass.getType().getSimpleName().toLowerCase()) {
                            case "integer":
                            case "int":
                                declaredFieldInClass.set(newStudentObject, Integer.valueOf(valueField));
                                break;
                            case "float":
                                declaredFieldInClass.set(newStudentObject, Float.valueOf(valueField));
                                break;
                            case "boolean":
                                declaredFieldInClass.set(newStudentObject, Boolean.valueOf(valueField));
                                break;
                            default:
                                declaredFieldInClass.set(newStudentObject, valueField);
                        }
                        declaredFieldInClass.setAccessible(false);
                    } else {
                        //there are children in the current node
                        NodeList modulesObjectList = studentFieldList.item(i).getChildNodes();
                        String nameField = studentFieldList.item(i).getAttributes().getNamedItem("name").getTextContent();
                        Field declaredFieldInClass = newStudentObject.getClass().getDeclaredField(nameField);
                        List<Object> modules = new ArrayList<>();
                        //adds the modules into the array
                        for (int j = 0; j < modulesObjectList.getLength(); j++) {
                            if (modulesObjectList.item(j).getNodeType() != Node.TEXT_NODE) {
                                //recursively calls the the loadObjectElement method for any sub lists
                                modules.add(loadObjectElement(modulesObjectList.item(j)));
                            }
                        }
                        //sets the modules of the specific student that the method is working with
                        declaredFieldInClass.set(newStudentObject, modules);
                    }
                }
            }
            return newStudentObject;
        }
    
    0 讨论(0)
提交回复
热议问题