Custom Java method that can take a target as parameter - java

I am an intermediate Java programmer, and very often use methods that are able to take a target as a parameter. Methods such as:
String.substring();
String.indexOf();
So I was wondering, how do I create a method that can take a target String, etc.?

String.substring(); and String.indexOf(); are examples of instance methods of the String class. They are methods that act on objects of that class.
String is a final class in Java, and as such it can not be extended to add your own methods to it. You'll have to create your own class.
Perhaps, for example:
public class MyString {
private String s;
public new(String newValue) {
s = newValue;
}
public someNewMethod() {
//do stuff
}
}
Now, on object of your MyString class, you can do this...
MyString ms = new MyString("Hello World.");
ms.someNewMethod();

Related

Is there a way in Java to build custom types based on java.lang base Types (e.g. String)?

is there a way in Java to create a custom class based on a primitive Java base class to give the derived class a semantic?
Example: I want to create a LinkedHashMap<LastName, Age> ages where LastName is a custom type of String and Age a custom type derived from Integer. I just tried to create my own class
public class LastName extends String {
//(no code in here, LastName has the same functionality as String)
}
but this is not possible. Is there another way to achieve what I want?
What you probably want is type-aliases. Java does not support this.
The best way would be to create a wrapper class, something like this:
class LastName{
private String value;
}
Another way is to name your variables correctly, eg don't do:
String string = "Smith";
But rather do:
String lastName = "Smith";
or just document your code with comments and javadoc.
Sidenote: If you still want to use type aliases you may want to use the Kotlin programming language which can compile to java-code (and more).
NO
Those classes are final.
Usual way to deal with it is to create wrapper class.
For example:
public class LastName {
private final String value;
public LastName(String value) {
this.value = value;
}
public String get() { return value; }
}
A String implements a CharSequence interface, just like StringBuffer and StringBuilder class. You can follow the same process.
public final class LastName implements CharSequence {
...
}

Java casting an object passed to method to its original type

I have a list called itemsData of object of class EtcStruct, but the class can differ depending on the file i want to use (the class is full of variables setters and getters):
ObservableList<EtcStruct> itemsData = FXCollections.observableArrayList();
Im passing it to the method thats supposed to work for any object type i choose and run invoked method from the file.
public static void parseToFile(ObservableList itemsData){
EtcStruct itemObject = (EtcStruct) itemsData.get(0);
System.out.print((int)reflectedmethod.invoke(itemObject);
}
Code above works , but what i want to achieve is make the method work without editing it's object type to make it more flexible for whatever structclass i plan to use.
I tried something with passing Struct Class name and .getClass() it returns the original type but i dont know what to do with it to make the new object of itemsData original type and cast the itemsData object.
public static void parseToFile(ObservableList itemsData,Class c){
Object itemObject = c.newInstance();
Object newobject = curClass.newInstance();
newobject = c.cast(itemsList.get(0));
}
Above seemed dumb to me and obviously didnt work.
After reading your comment I understand better why one would use reflection in your case. A GUI builder/editor is an example where reflection is used to provide an interface to set/get the values of components. Still, IMHO, reflection isn't a tool you would design for when you own the classes and are the primary designer. If possible you should strive for something more like this:
interface Parsable {
default int parse() {
System.out.println("Here I do something basic");
return 0;
}
}
class BasicStruct implements Parsable { }
class EtcStruct implements Parsable {
#Override
public int parse() {
System.out.println("Here I do something specific to an EtcStruct");
return 1;
}
}
// If some structs have a parent-child relationship
// you can alternatively `extend EtcStruct` for example.
class OtherStruct extends EtcStruct {
#Override
public int parse() {
super.parse();
System.out.println("Here I do something specific to an OtherStruct");
return 2;
}
}
void parseToFile(Parsable parsable) {
System.out.println(parsable.parse());
}
// If you use a generic with a specific class you don't
// have to guess or care which kind it is!
void parseToFile(ObservableList<Parsable> parsables) {
for (Parsable p : parsables) {
parseToFile(p);
}
}
public static void main(String[] args) {
ObservableList<Parsable> parsables = FXCollections.observableArrayList();
parsables.add(new BasicStruct());
parsables.add(new EtcStruct());
parsables.add(new OtherStruct());
parseToFile(parsables);
}
Output:
Here I do something basic
0
Here I do something specific to an EtcStruct
1
Here I do something specific to an EtcStruct
Here I do something specific to an OtherStruct
2
Of course, this is just an example that needs to be altered to meet your needs.
But what I still don't get is if you're able to parse from a file why you can't parse to one. Nonetheless, I slapped some code together to show you how I might parse an object to a file, manually, when dealing with Objects only.
The idea is to satisfy a bean-like contract. That is, each structure should provide a parameter-less constructor, all fields you want managed by reflection will follow Java naming convention and will have both a public setter and getter.
Don't get caught up in the file writing; that will be determined by your needs. Just notice that by following this convention I can treat any Object as a parsable structure. A less refined version here for reference:
public void parseToFile(Object object) throws IOException, InvocationTargetException, IllegalAccessException {
fos = new FileOutputStream("example" + object.getClass().getSimpleName());
List<Method> getters = Arrays.stream(object.getClass().getMethods())
.filter(method -> method.getName().startsWith("get") && !method.getName().endsWith("Class"))
.collect(Collectors.toList());
for (Method getter : getters) {
String methodName = getter.getName();
String key = String.valueOf(Character.toLowerCase(methodName.charAt(3))) +
methodName.substring(4, methodName.length());
fos.write((key + " : " + String.valueOf(getter.invoke(object)) + "\n").getBytes());
}
fos.close();
}
I think that you can just still use Generics to keep static objects typing. Try to parametrize your function parseToFile. Here is an example:
public static void parseToFile(ObservableList<EtcStruct> itemsData){
EtcStruct itemObject = itemsData.get(0);
System.out.print((int)reflectedmethod.invoke(itemObject);
}

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.

Inherited enum redefinition

It is more complex than it sounds, but I think I am obliged to try something like it. I want to make an abstract parent class with a prototyping of an enum (I want to declare the enum with only one value probably that will be the default unitialized one and also declaring a couple of methods that I will be using from the subclass), then I want to class that will extend the abstract parent to actually intialize the very same enum (I know that this practically hides the parent enum) so that the kid class will define a set of items inside the enum, but keep the methods probably.
I do not know much about this level of abstraction so I will now describe the nature of my problem, in case there is a more practical solution:
I have a bunch of files that contain classes that implement a lot of commands based on enums. (e.g. class1 implements Observer has an update method that uses an enum-based switch to decide what command was picked, same applies for the other classes) I now want to abstract this whole thing in a way that I have an enum variable with the exact same name in all classes (e.g. CommandSet) so that I can have a generic method inside the parent that will be able to print a help list to my system using the inside methods of the enum. Now I know I can rewrite the exact same method in every class, but I want to abstract it so that others can keep on extending the library I am making!
Hopefully I am not too confusing or too confused and somone can help me! :)
Edit: Here is an idea of the code (Probably not right):
public abstract class Commands{
enum CommandSet{
// empty command, placeholder
null_command ("command name", "command description");
// the Strings used for name and description
private final String name;
private final String description;
// constructor
CommandSet(String name, String description){
this.name=name;
this.description=description;
}
// get parameters
public String getName(){
return name;
}
public String getDescription(){
return description;
}
}
public void showHelp(){
for (CommandSet i : CommandSet.values()) {
printf(i.getName(),":",i.getDescription());
}
}
}
public class StandardCommads extends Commands implements Observer{
// I want to change the enum here, just changing the values so that null_command ("command name", "command description") will get removed and I will add a dozen other values, but keep the methods that the parent had
// update inherited from Observer
#Override
public void update(Observable observable, Object object) {
// I want the commands inside the switch cases defined inside this class's enum
switch(CommandSet.valueOf(String.valueOf(object)){
case command1: doStuff1();break;
case command2: doStuff2();break;
...
case commandN: doStuffN();break;
}
// other methods
void doStuff1(){
...
}
...
void doStuffN(){
...
}
}
public class NonStandardCommads extends Commands implements Observer{
// Another set of commands here for the enum keeping the same methods it had in the parent
// update inherited from Observer
#Override
public void update(Observable observable, Object object) {
// Other set of commands inside this class used in the switch statement
switch(CommandSet.valueOf(String.valueOf(object)){
case Zcommand1: doStuffz1();break;
case Zcommand2: doStuffz2();break;
...
case ZcommandN: doStuffzN();break;
}
// other methods
void doStuffz1(){
...
}
...
void doStuffzN(){
...
}
}
Impossible: Java enums can neither extend another class nor be extended themselves.
They can however implement interfaces. Perhaps you can use that to your advantage.
There is something else about enums that may help you: enums are not immutable. You could change field values of the enums, however that would change them for the whole JVM.
Another approach maybe to pass your subclass instances into a method of the enum and have the enum use your subclass as a call back to get different functionality out of an enum for a different user of the enum.
Nope, you can't do that.
Java Enums run out of gas very quickly & definitely, when you want to add/extend more definitions or instantiate the enum instances, at a later time. (eg load them from database, configure them in an instance method, not just statically.)
Behaviour/ or logic in Java enums is kinda limited too -- you can define & set properties, but only what's statically initializable, and logic seems basic (you end up mainly just comparing references or ordinals, with the other defined enum constants).
What you can do:
You can implement an ancestor Command or AbstractCommand class, with a integer Code, and then subclass it to define concrete values/ additional codes/ load or configure instances, etc.
For further benefit, you get efficient switch & despatch (by Code) plus the ability to define further details/properties, instantiate commands as-needed, etc.
Essentially, this is how you used to define an Enum before Java supported them. Though you may be using them as value objects, rather than strictly static.
My expertise:
I've done extensive compiler & type-system work, tried enums for file-types and associated data/behaviour.. explored the outer limits, and reached the definite boundaries.
I also like being able to instantiate & return a new UnknownFileType("") as an answer, too. Enums can't do that.
Example:
(We'll despatch by String, not int -- since your code appears to be using Java 7. This makes command resolution easier, than requiring both a syntactical "name" and an internal integer "code".)
public static class Command {
protected String code;
protected String desc;
public String getCode() {return code;}
public String getDesc() {return desc;}
public Command (String code, String desc) {
this.code = code;
this.desc = desc;
}
public String toString() {return code;}
}
public class StandardCommands {
public static Command READ = new Command("READ", "read a record");
public static Command CREATE = new Command("WRITE", "create a record");
public static Command EDIT = new Command("WRITE", "modify a record");
}
public class FurtherCommands extends StandardCommands {
public static Command LIST = new Command("LIST", "list all records");
}
public class QueryCommands extends FurtherCommands {
public static class QueryCmd extends Command {
protected String search;
public String getSearch() {return search;}
// constructor..
}
public static QueryCmd QUERY_EXAMPLE = new QueryCmd("QUERY", "example", "query for specified string");
public static QueryCmd createQuery (String search) {
return new QueryCmd( "QUERY", search, "query for specified string");
}
}

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

Categories