Search code examples
javaclass-designclassloader

Is it possible to find an instance of an object without it being passed to the method?


I have a parser class "MessageParser" which i pass a message which is of type "String" to it for it to be parsed. The parsing method signature for the class is

public void parse(String message);

I need to pass an instance of "Properties" to it but i dont want to change the signature of the method to add a new argument to it. I have been struggling with this for the last couple of days and have tried a couple of options - see Sending in an object of type Object instead of String - Polymorphism

The class that calls the parsing method "ParserManager" knows of the properties object. Is there a way for the MessageParser to find the properties object without it being passed to it?

Edit

Here is some example code. I would like the "MessageCparser" to access the "prop" object in "ParserManager" without changing anything in the "Parser" interface or the "ParserManager" class. Is this possible?

public interface Parser{
    public void parse(String message);
}

public class MessageCParser implements Parser{
    public void parse(String message){
        MessageObject mobject = (MessageObject)message; 
        System.out.println("Parsing C" + mobject.getMessage());
    }

    public void parse(String m){}
}


import java.util.HashMap;

public class ParserManager{

Properties prop = null;

    public ParserManager() {
        prepare();
    prop = new Properties()
    }

    HashMap parsers = new HashMap();


    public void prepare(){

        parsers.put("A",new MessageCParser());

    }

    public void parseMessage(String msgType, String message){
        ((Parser)parsers.get(msgType)).parse(message);
    }
}

Thanks


Solution

  • The most evident solution would be to add a reference to the Properties object as a field in the ParserManager, and then either provide the ParserManager with the properties object as a constructor argument or through a setter-method as shown below:

    class ParserManager {
        ...
        Properties props;
    
        public void setParsingProperties(Properties props) {
            this.props = props;
        }
    
        public void parse(String message) {
            // props available here, without being passed as agurment.
        }
    }
    
    class CallingParserManager {
        ...
        void someMethod() {
            ...
            parserManager.setParsingProperties(propertiesToUse);
            parserManager.parse(theString);
            ...
        }
        ...
    }
    

    Looking at your previous question, I'd say it would be fine if you added a setParsingProperties in the Parser interface. The method can be implemented as an empty method for those parser that don't need the properties.


    Regarding your edit: No, it's not possible to solve it like that.

    MessageObject mobject = (MessageObject) message;
    

    Will only work if MessageObject is a subtype of String (but since String is final (can't be extended) that cannot be the case).

    The dirty quick-fix would be to check (with instanceof) if the Parser is an instance of MessageCParser and cast it and then use a MessageCParser specific parse method that takes the Properties as an argument.