Java: getting strings from enum without having to call .toString()? - java

Say I have this enum:
public class MyErrors {
public enum Errors {
BAD_FILE_PATH("Please point to a valid file");
private final String message;
Errors(final String message) {
this.message = message;
}
#Override
public String toString() {
return message;
}
}
And this call:
Logging.log(Level.INFO, MyErrors.Errors.BAD_FILE_PATH.toString());
It seems so verbose to me to have to call .toString(). Isn't there a way to just call the enum itself and have it return its string by default?
Ideally I'd like something like MyErrors.BAD_FILE_PATH --> which returns a string so it's not so verbose. Does that make any sense?

Both of these work for me in Eclipse:
LOG.info(Errors.BAD_FILE_PATH); // Using Log4j
System.out.println(Errors.BAD_FILE_PATH);
These two methods take an Object parameter. And since are not receiving Strings, the logic in those methods must call the toString() method on the passed in object to obtain a string.
The log() method of java.util.logging.Logger does not support an Object parameter. Instead, it is expecting a String parameter; thus, the logic in this method has no need to call toString().
What you are looking for is a new signature for the Logger that supports an Object parameter. However, I don't know that extending the Logger is a straight forward process or advisable; see here.
Another option would be to use Log4j.

Related

Interface that extracts a boolean or String

So I have a data class that is somewhat laid out as:
class MyData {
String str1,str2,str3;
Boolean bool1,bool2;
}
The attributes are to be populated based upon a String input, something like:
public void populate(String s) {
if(s.contains("somevalue") myData.setStr1("xxx");
if(s.constains("something else") myData.setBool1(true);
else myData.setBool1(false);
}
This is, of course, a pretty horrible way to do things as s.contains are actually some pretty hairy conditions, so instead I defined an interface:
public interface DataFinderInterface {
public String findStringData(final String input);
public Boolean findBooleanData(final String input);
}
Therefore the populate method could be rewritten as:
public void populate(String s) {
myData.setStr1(str1Finder.findStringData(s));
myData.setBool1(bool1Finder.findBooleanData(s);
}
The implementations of this interface either define a findStringData or a findBooleanData, which is quite unsatisfying. The populate method needs to know if we are expecting to use the findStringData method or the findBooleanData method.
Is there a better way to do this? Am I being overly picky, because the populate method needs to know what instance of DataFinderInterface to assign to what field anyway?
A single findData method returning a String should be sufficient: the code that processes Booleans can put a call to Boolean.getBoolean() on top of it:
public interface DataFinderInterface {
public String findData(final String input);
}
...
myData.setBool1(Boolean.getBoolean(bool1Finder.findData(s));
The problem with the above (or ONE of the problems) is that you are always calling setStr1 AND setBool1 and I assume you will be calling all of the others as well.
If you MUST use something like the above pattern you might want to consider having MyData hold AtomicRefernce<String> and AtomicReference<Boolean>. Then have getSettableString and getSettableBoolean methods that returns the appropriate reference or null if no match.
If it is only the interface method signature you are worried about this could be solved using generics. However it does seem a little weird to initialize an object from a string that way. Perhaps if you add more details about what problem you are trying to solve, there might be a better solution.
public interface DataFinder<T> {
public T findData(final String input);
}
DataFinder<String> str1Finder = new ... // a class implementing DataFinder<String>
DataFinder<Boolean> bool1Finder = new ... // a class implementing DataFinder<Boolean>
public void populate(String s) {
myData.setStr1(str1Finder.findData(s));
myData.setBool1(bool1Finder.findData(s);
}
Consider using regular expressions to extract the data you need from the input string. I would leave the MyData class as a simple data container and build a separate class for populating it - for example, a MyDataBuilder. This class could use string matching in order to extract the fields and populate them on the object.

how to reduce the code of constructor overloading

In my one class I have many constructors like this..
public MyData(int position,String songName,String duration, boolean e) {
//initialization of above variable like int, string,string and boolean
}
public MyData(String songName, String artistName, String duration,String downloadPath, String songSize, String albumName,String url,String trackId, boolean e)
{
//initialization of above variable like String,String,String,String,String,String,String,String and boolean
}
and some more like above.
Now the calling time, I'm calling that constructor only that I require data. but I don't think my flow is good so I need some help to reduce my code as well as creation of good flow.
If anybody have a good flow to achieve this, then please share.
Thanks in advance.
Assuming you're effectively applying defaults, usually the best approach is to have one "full" constructor and make the others call it. For example:
public Foo(String name)
{
// Default the description to null
this(name, null);
}
public Foo(String name, String description)
{
this.name = name;
this.description = description;
}
You still end up with quite a lot of cruft in terms of overloaded constructors, but at least each of those "extra" constructors contains no actual code - just a call to another constructor. If possible, chain the constructors together so that the default for any particular value is only specified in one place - or use a constant. That way you get consistency.
Another option is to use a "parameter object" following the builder pattern - create another class whose sole purpose is to hold the data for the constructor parameters. This should be mutable, with setters for all of the different values. Often it's useful to make the setters return the builder, so you can use:
FooParameters parameters = new FooParameters()
.setName("some name")
.setDescription("some description");
// Either a constructor call at the end, or give FooParameters
// a build() or create() method
Foo foo = new Foo(parameters);
This is particularly useful if the main type you're constructing is an immutable type - it means you can apply conditional logic in the calling code to set some parameters but not others. The Java framework itself uses this approach in ProcessBuilder, although personally I'm not keen on the way it overloads method names to either return a value or set a value based on whether you provide an argument :(
Note the comment above the constructor call in the final snippet - if your helper class is only ever helpful for creating objects of a single type, you can give it an extra method (build, create, start, whatever is most appropriate) to take the place of the constructor call. This allows you to build the whole final object in a fluent way.
One option in the Java implementation of the builder pattern is to use a nested type, e.g.
Foo foo = new Foo.Builder().setName(...).setDescription(...).build();
That avoids polluting your package with another class which is only useful for building instances of Foo.
You may want to have another object that is responsible for creating the object through the builder pattern. For example, you could define an object like this:
public class SongBuilder {
private String artistName;
private String songTitle;
/* ... everything else ... */
public SongBuilder setArtistName(String name) {
this.artistName = name;
return this;
}
public SongBuilder setSongTitle(String title) {
this.songTitle = title;
return this;
}
/* ... everything else ... */
public Song create() {
return new Song(artistName, songTitle, /* ... everything else ... */);
}
}
You could then define a single constructor for Song that takes in all the data. To make a Song, you could then write
Song s = new SongBuilder().setSongTitle("Still Alive").setArtistName("GLaDOS").create();
The advantage of this approach is that you can set a reasonable default for all the parameters, then just call the appropriate set functions for parameters that you actually use. It also allows you to add new parameters easily without having to go back and rewrite important code.
Alternatively, as Jon Skeet points out, you can have multiple constructors that all call one another. The advantage of the builder pattern over this approach is that if you have n different parameters, there are 2n combinations of constructors you'd need to write, whereas you only need one builder.
Hope this helps!

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
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.
Well, there are four ways of getting information, broadly speaking:
It could be part of the state of the object that the method is called on (e.g. it could be passed to the constructor and then retained in a field)
It can be a parameter of the method itself
It could be accessed statically, e.g. via a singleton
It could be accessed via a thread-local variable
All of these can be used with indirection of course - for example, if something else which knows about the Properties is available via one of the above mechanisms, then you can get to that and then find out about the Properties. But you can't just find out the calling object and ask that.
What do you need to do with the Properties in question? Would the Properties vary on a call-by-call basis for the same MessageParser? If so, it really should be a parameter. You say you don't want to change the signature of the method - but if you want to pass more information in, that's exactly what you should do.
If you have only one instance of your "Properties" object, you can use something like the Singleton pattern.
You can also add a reference to the ParserManager somewhere in your MessageParser and then call a method on ParserManager which will return the Properties, but without some code snippets it's impossible to help you further than this.

How to get string name of a method in java?

How can I find out through reflection what is the string name of the method?
For example given:
class Car{
public void getFoo(){
}
}
I want to get the string "getFoo", something like the following:
Car.getFoo.toString() == "getFoo" // TRUE
You can get the String like this:
Car.class.getDeclaredMethods()[0].getName();
This is for the case of a single method in your class. If you want to iterate through all the declared methods, you'll have to iterate through the array returned by Car.class.getDeclaredMethods():
for (Method method : Car.class.getDeclaredMethods()) {
String name = method.getName();
}
You should use getDeclaredMethods() if you want to view all of them, getMethods() will return only public methods.
And finally, if you want to see the name of the method, which is executing at the moment, you should use this code:
Thread.currentThread().getStackTrace()[1].getMethodName();
This will get a stack trace for the current thread and return the name of the method on its top.
Since methods aren't objects themselves, they don't have direct properties (like you would expect with first-class functions in languages like JavaScript).
The closest you can do is call Car.class.getMethods()
Car.class is a Class object which you can use to invoke any of the reflection methods.
However, as far as I know, a method is not able to identify itself.
So, you want to get the name of the currently executing method? Here's a somewhat ugly way to do that:
Exception e = new Exception();
e.fillInStackTrace();
String methodName = e.getStackTrace()[0].getMethodName();
Look into this thread:
Getting the name of the currently executing method
It offers some more solutions - for example:
String name = new Object(){}.getClass().getEnclosingMethod().getName();
With Java 8, you can do this with a few lines of code (almost) without any additional libraries. The key is to convert your method into a serialisable lambda expression. Therefore, you can just define a simple interface like this:
#FunctionalInterface
public interface SerializableFunction<I, O> extends Function<I, O>, Serializable {
// Combined interface for Function and Serializable
}
Now, we need to convert our lambda expression into a SerializedLambda object. Apparently, Oracle does not really want us to do that, so take this with a grain of salt... As the required method is private, we need to invoke it using reflections:
private static final <T> String nameOf(SerializableFunction<T, ?> lambda) {
Method findMethod = ReflectionUtils.findMethod(lambda.getClass(), "writeReplace");
findMethod.setAccessible(true);
SerializedLambda invokeMethod = (SerializedLambda) ReflectionUtils.invokeMethod(findMethod, lambda);
return invokeMethod.getImplMethodName();
}
I'm using Springs ReflectionUtils class here for simplicity, but you can of course replace this by manually looping through all superclasses and use getDeclaredMethod to find the writeReplace method.
And this is it already, now you can use it like this:
#Test
public void testNameOf() throws Throwable {
assertEquals("getName", nameOf(MyClassTest::getName));
}
I haven't checked this with Java 9s module system, so as a little disclaimer it might be more tricky to do this with more recent Java versions...
try this,
import java.lang.reflect.*;
public class DumpMethods {
public static void main(String args[]) {
try {
Class c = Class.forName(args[0]);
Method m[] = c.getDeclaredMethods();
for (int i = 0; i < m.length; i++)
System.out.println(m[i].toString());
} catch (Throwable e) {
System.err.println(e);
}
}
}
Wait, since you already know the method name, can't you just type it as a string?
Instead of (pseudo) Class.methodName.toString(), just use "methodName".
Otherwise you can use Class#getDeclaredMethods() to get all the methods in a class

can constructors actually return Strings?

I have a class called ArionFileExtractor in a .java file of the same name.
public class ArionFileExtractor {
public String ArionFileExtractor (String fName, String startText, String endText) {
String afExtract = "";
// Extract string from fName into afExtract in code I won't show here
return afExtract;
}
However, when I try to invoke ArionFileExtractor in another .java file, as follows:
String afe = ArionFileExtractor("gibberish.txt", "foo", "/foo");
NetBeans informs me that there are incompatible types and that java.lang.String is required. But I coded ArionFileExtractor to return the standard string type, which is java.lang.string.
I am wondering, can my ArionFileExtractor constructor legally return a String?
I very much appreciate any tips or pointers on what I'm doing wrong here.
Constructors create objects, they don't return data.
Your method, ArionFileExtractor(), is not a constructor. Consutructors do not have return types, and look like this:
public ArionFileExtractor (String fName, String startText, String endText) {
//...
}
Note the lack of a return type.
A constructor can only return an instance of object that it constructed - otherwise you have no reference against which to hang on to the object you just created! If you want to make a "utility" call, consider a static method:
public class ArionFileExtractor {
public static String getFileContents(String fName, String startText, String endText) {
String afExtract = "";
// Extract string from fName into afExtract in code I won't show here
return afExtract;
}
}
Which can be invoked using
ArionFileExtractor.getFileContents(...)
As much as this is surprising, the code you made has a default no argument constructor. ArionFileExtractor is a method that returns a String. I was quite surprised when I first saw code that did this, as it is certainly an accident (as in your case).
You could call you method (just to show this is the case) with:
String afe = new ArionFileExtractor().ArionFileExtractor("gibberish.txt", "foo", "/foo");
What it really sounds like you are trying to get at is a static method, not a class at all.
public class ArionFileExtractor() {
public static String extract(String fName, String startText, String endText) {
String afExtract = "";
// Extract string from fName into afExtract in code I won't show here
return afExtract;
}
}
which you would call with:
String afe = ArionFileExtractor.extract("gibberish.txt", "foo", "/foo");
Constructor is not a regular method. It always returns instance of the class that it belongs to. In your example ArionFileExtractor. There is no way to return any other instance.
Notice that you can't specify return type for constructor explicitly nor use return keyword (illegal in this context).
Java compiler treats ArionFileExtractor as an instance method,
String afe = new ArionFileExtractor().ArionFileExtractor("gibberish.txt", "foo", "/foo");
Constructor can only return instance of its class. It cannot return String.
For instance if you have class SampleClass, constructor can return only object of class SampleClass.
No it should not be able to legally return a String. I'm not sure why Netbeans didn't simply barf at you when you tried to. Maybe it tried to compile it as some sort of static method. Constructors do not generally have return types in code, because when they are compiled they are assigned to return an instance of the class they are constructing.
The easiest (though not necessarily best) way to adapt your code would be to have an empty constructor and turn the current constructor into a static method like this:
public class ArionFileExtractor {
private ArionFileExtractor() {}
public static String ExtractFile(String fName, String startText, String endText) {
String afExtract = "";
// Extract string from fName into afExtract in code I won't show here
return afExtract;
}
}
The private constructor makes it so that ArionFileExtractor can only be used statically and cannot be instantiated. Then when you use it you simply do this:
String afe = ArionFileExtractor.ExtractFile("gibberish.txt", "foo", "/foo");
Be warned, using static classes is sometimes considered bad form - depending on the situation. So it might be worth while to try and come up with a different way to do this.
No.
A constructor does not really return anything. Instead it builds the object in question.
It looks like you want a utility method here:
public class Whatever {
public static String doStuff(String s) {
return s;
}
}
Yes.Only String class constructor can return string objects out of it ;).
This basically means that the constructor creates the object of the class you are calling.
You need to FIRST create the object (using the constructor) and THEN do stuff with it.
Java has very few smart shortcuts. I

Categories