I want to generate toString() method for a class extending an other one. But in generate toString() dialog, there is no checkbox for inherited fields (see picture below)
What's the problem here ?
The Inherited fields option will turn out if:
You are extending a class with inheritable fields, i.e. public, protected (or package-protected within the same package)
You are generating the toString method contextually to a right-click when your cursor is within the child class
The latter can be confusing: it's not where you right-click, but where your actual cursor is, that determines for which class the toString (et al.) method should be generated.
You have to write a toString() method in the superclass and then you need to select the inherited method and select toString() there.
Bit late, but consider using the reflectionToString method in the ToStringBuilder class in the Apache Commons library rather than implementing your own toString method for each class. You can use it like this:
public String toString() {
ToStringBuilder.reflectionToString(this)
}
It'll dynamically generate a String based on all the fields in your class, including those in any superclasses.
You can also tune the output a bit if you want different behaviour for some cases (excluding some fields, not including inherited fields etc).
I know this is slightly off-topic, but someone might prefer the following code:
public String toString() {
StringBuilder toReturn = new StringBuilder("\r\n-------------\r\n");
Class<?> c = this.getClass();
toReturn.append(c.getName()).append("\r\n");
Method[] methods = c.getMethods();
for (Method method : methods) {
if (method.getName().startsWith("get") && !method.getName().equals("getClass")) {
Object obj = new String("no value");
try {
obj = method.invoke(this, (Object[]) null);
} catch (Throwable e) {
}
toReturn.append(method.getName()).append(" -> ").append(obj).append("\r\n");
}
}
toReturn.append("-------------\r\n");
return toReturn.toString();
}
Related
I'm learning java design patterns and I wonder if I can apply some with following problem. I have class Solider and some child classes, for example: General and Sergeant. I'm creating Solider object and in runtime I want to change this object to General or Sergeant object, or create new Sergeant or General object using created earlier Solider object:
Solider s = new Solider(...);
.....
if (generalCondition) {
General g = createGeneralFromSolider(s);
//or better:
//General g = promoteSoliderToGeneral(s);
} else if (sergeantCondition) {
Sergeant sr = createSergeantFromSolider(s);
//or better:
//Sergeant sr = promoteSoliderToSergeant(s);
}
Firstly I decided to create additional constructor in General/Sergeant Class:
Class General extends Solider {
General(Solider s, Map<String, String> generalSpecificParams) {
//first we are going to copy all solider params to general params (bad idea if we have a lot of params)
this.setParamX(s.getParamX());
....
//then we can assign the rest of general-specific params
this.setGeneralSpecificParams(generalSpecificParams);
}
}
and use it in methods createGeneralFromSolider but I'm not sure if it is elegant way. Main disadvantage is that I create new object, so after calling createGeneralFromSolider I have 2 object in memory. I would rather have one object in memory: General/Sergeant promoted from Solider (object General/Sergeant which earlier was the Solider object). I wonder if I can use some design patter to resolve it. I remember that in C++ there has been something like copying constructors which copying all params from one object to another by assigning all params, one after another. In Java I didn't hear about anything similar.
You would probably need to use a Factory pattern for this kind of situation.
For example:
public class SoldierFactory {
//use getSoldier method to get object of type Soldier
public Soldier getSoldier(String soldierType){
if(soldierType == null){
return null;
}
if(soldierType.equals("case1")){
return new General();
} else if(soldierType.equals("case2")){
return new Sergeant();
} else if(.....
}
return null;
}
}
public class FactoryPatternDemo {
public static void main(String[] args) {
SoldierFactory soldierFactory = new SoldierFactory();
Soldier s1 = soldierFactory.getsoldier("case1");
}
}
I think its better to not create the Soldier ahead of calling Soldier factory. You're going to change it regardless during run-time right?
First of all, when constructing child classes, use super as the first statement of the constructor like so:
class Soldier {
private String rank; // e.g. Pvt, PFC, etc.
private int yearsOfService;
// ... (Standard constructor)
public Soldier(Soldier s) {
this.rank = s.rank; this.yearsOfService = s.yearsOfService;
}
// ... (Getters and Setters)
}
class Sergeant extends Soldier {
private int subordinates;
public Sergeant(Soldier s) {
super(s)
this.rank = "Sergeant"; // overwrites this Sergeant's rank
this.subordinates = 0;
}
}
You could easily encapsulate this in a promoteSoldierToSergeant method. However, this can lead to telescoping constructors if classes with many attributes are designed naively, or necessitate your map-based workaround. To resolve this, I'm personally a big fan of the Builder pattern, but you can also consider the Factory pattern.
Your question regarding "copying constructors" is perhaps best addressed by reading up on the Clonable interface, but be aware of the differences between shallow and deep copies, and the implications for your classes and data structures.
I think your approach is totally acceptable. If you have an object X, that you want to turn into Y, you can do it in Y constructor, copying all necessary fields.
You could as well use a builder, or static factory methods, but either way you'll have to copy fields, as there's no automatic copy constructor in java (except if you use some dedicated library such as lombok, which can provide full-args constructors from annotations)
You worry about having 2 objects in memory. But if you remove every reference of the original Soldier, the garbage collector will destroy it.
Last thing, as mentionned by #tsolakp , is it a good design to have General inheriting from Soldier? Couldn't it be just a "grade" variable, or something like that, to reflect this state? It's a common mistake to overuse inheritance where composition would be sufficient, and would cause less troubles.
What you want could be achieved using Reflections.
That way you can automatically copy fields from the instance of parent to child class.
Your code would look something like this:
public static void copyObject(Object src, Object dest)
throws IllegalArgumentException, IllegalAccessException,
NoSuchFieldException, SecurityException {
for (Field field : src.getClass().getFields()) {
dest.getClass().getField(field.getName()).set(dest, field.get(src));
}
}
public static General createGeneral (Solider solider, String devision) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
General general = new General();
copyObject(solider, general);
general.setDevision(devision);
return general;
}
The Field import is java.lang.reflect.Field;
========================================================================
Another way would be to use the Apache Bean Utils.
Than, you can use it's cloneBean(Object Bean) method like this:
General general = cloneBean(solider);
to copy the fields from solider to general and after that all the fields that are specific to child class (General).
========================================================================
EDIT: It would also be wise to introduce another child class that would be used for "ordinary" soliders if you intended to use the parent class Solider for "ordinary" soliders (which I suppose you do according to your commented method name promoteSoliderToGeneral(Solider s).
So, for example you would have a parent class called MilitaryMan and 3 child classes that extend it: Solider, General and Sergeant.
This way, you can uniformly handle all of the MilitaryMan. And, you can check if the MilitaryMan is a Solider, General or Sergeant with:
if (militaryMan instanceOf Solider) {
// do solider specific processing
...
} else if (militaryMan instanceof General) {
...
} else if (militaryMan instanceof Sergeant) {
...
}
I think it would be cleaner this way.
I have this code:
Class I want to copy:
public class NormalChair extends AbstractChair {
protected int height;
protected String name;
public NormalChair() {
super();
}
public NormalChair(String name, int height) {
super(name, height);
}
// Copy constructor - getName() and getHeight() are defined in parent class.
public NormalChair(NormalChair chair) {
this(chair.getName(), chair.getHeight());
}
}
Create some class
public Object createObj(String cls_name, String param1, int param2){
return Class.forName(cls_name).getConstructor(String.class, Integer.class).newInstance(param1, param2);
}
Then I try to copy object of that class using this:
Object obj_to_copy = createObj("Classname", "name", 10);
String cls_name = obj_to_copy.getClass().getName();
Class.forName(cls_name).getConstructor(Object.class).newInstance(obj_to_copy);
And I get this error:
Exception in thread "main" java.lang.NoSuchMethodException: test.NormalChair.<init>(java.lang.Object)
at java.lang.Class.getConstructor0(Class.java:2800)
at java.lang.Class.getConstructor(Class.java:1708)
at test.ProductTrader.create(ProductTrader.java:57)
at test.Test.main(Test.java:23)
So I suppose I need to call copy constructor somehow differently than showing it's type as Object?
P.S. Also I gave this example as simplistic. But in reality I would not know which class needs to be copied before runtime, so using copy constructor should not depend only on NormalChair class.
Update:
I updated my question, to make it more clear that when I copy object, before, runtime, I won't know what class it will need to copy.
Java reflection for some reason matches classes and method signatures strictly. So in order to find a matching constructor, you would need to enumerate available constructors with Class.getDeclaredConstructors() and find a matching one.
I have written a small library to simplify the task, here is a method matching class from it: HavingMethodSignature.
If you're interested, here is how you create a new instance with this lib:
Object o = OpenBean.newInstance(Class.forName(cls_name));
Why bother with a copy constructor in Java ? There is a standard way to copy an object in Java : simply clone it. If default cloning is not relevant, override the clone() method.
You simply need to write obj.clone() to get a copy.
see Java documentation of clone() for details.
If you can assume that a copy constructor accepts an object of the same class, you can do something like:
class ObjectCopier {
public static Object copy(Object orig) {
Class<?> cls = orig.getClass();
Constructor<?> con = cls.getDeclaredConstructor(cls);
return ((con == null) ? null : con.newInstance(orig);
}
}
(untested, so treat it as such)
I often find I want to do something like this:
class Foo{
public static abstract String getParam();
}
To force a subclasses of Foo to return a parameter.
I know you can't do it and I know why you can't do it but the common alternative of:
class Foo{
public abstract String getParam();
}
Is unsatisfactory because it requires you to have an instance which is not helpful if you just want to know the value of the parameter and instantiating the class is expensive.
I'd be very interested to know of how people get around this without getting into using the "Constant Interface" anti pattern.
EDIT: I'll add some more detail about my specific problem, but this is just the current time when I've wanted to do something like this there are several others from the past.
My subclasses are all data processors and the superclass defines the common code between them which allows them to get the data, parse it and put it where it needs to go.
The processors each require certain parameters which are held in an SQL database. Each processor should be able to provide a list of parameters that it requires and the default values so the configuration database can be validated or initialised to defaults by checking the required parameters for each processor type.
Having it performed in the constructor of the processor is not acceptable because it only needs to be done once per class not once per object instance and should be done at system startup when an instance of each type of class may not yet be needed.
The best you can do here in a static context is something like one of the following:
a. Have a method you specifically look for, but is not part of any contract (and therefore you can't enforce anyone to implement) and look for that at runtime:
public static String getParam() { ... };
try {
Method m = clazz.getDeclaredMethod("getParam");
String param = (String) m.invoke(null);
}
catch (NoSuchMethodException e) {
// handle this error
}
b. Use an annotation, which suffers from the same issue in that you can't force people to put it on their classes.
#Target({TYPE})
#Retention(RUNTIME)
public #interface Param {
String value() default "";
}
#Param("foo")
public class MyClass { ... }
public static String getParam(Class<?> clazz) {
if (clazz.isAnnotationPresent(Param.class)) {
return clazz.getAnnotation(Param.class).value();
}
else {
// what to do if there is no annotation
}
}
I agree - I feel that this is a limitation of Java. Sure, they have made their case about the advantages of not allowing inherited static methods, so I get it, but the fact is I have run into cases where this would be useful. Consider this case:
I have a parent Condition class, and for each of its sub-classes, I want a getName() method that states the class' name. The name of the sub-class will not be the Java's class name, but will be some lower-case text string used for JSON purposes on a web front end. The getName() method will not change per instance, so it is safe to make it static. However, some of the sub-classes of the Condition class will not be allowed to have no-argument constructors - some of them I will need to require that some parameters are defined at instantiation.
I use the Reflections library to get all classes in a package at runtime. Now, I want a list of all the names of each Condition class that is in this package, so I can return it to a web front end for JavaScript parsing. I would go through the effort of just instantiating each class, but as I said, they do not all have no-argument constructors. I have designed the constructors of the sub-classes to throw an IllegalArgumentException if some of the parameters are not correctly defined, so I cannot merely pass in null arguments. This is why I want the getName() method to be static, but required for all sub-classes.
My current workaround is to do the following: In the Condition class (which is abstract), I have defined a method:
public String getName () {
throw new IllegalArugmentException ("Child class did not declare an overridden getName() method using a static getConditionName() method. This must be done in order for the class to be registerred with Condition.getAllConditions()");
}
So in each sub-class, I simply define:
#Override
public String getName () {
return getConditionName ();
}
And then I define a static getConditionName() method for each. This is not quite "forcing" each sub-class to do so, but I do it in a way where if getName() is ever inadvertently called, the programmer is instructed how to fix the problem.
It seems to me you want to solve the wrong problem with the wrong tool. If all subclasses define (can't really say inherit) your static method, you will still be unable to call it painlessly (To call the static method on a class not known at compile time would be via reflection or byte code manipulation).
And if the idea is to have a set of behaviors, why not just use instances that all implement the same interface? An instance with no specific state is cheap in terms of memory and construction time, and if there is no state you can always share one instance (flyweight pattern) for all callers.
If you just need to couple metadata with classes, you can build/use any metadata facility you like, the most basic (by hand) implementation is to use a Map where the class object is the key. If that suits your problem depends on your problem, which you don't really describe in detail.
EDIT: (Structural) Metadata would associate data with classes (thats only one flavor, but probably the more common one). Annotations can be used as very simple metadata facility (annotate the class with a parameter). There are countless other ways (and goals to achieve) to do it, on the complex side are frameworks that provide basically every bit of information designed into an UML model for access at runtime.
But what you describe (processors and parameters in database) is what I christened "set of behaviors". And the argument "parameters need to be loaded once per class" is moot, it completely ignores the idioms that can be used to solve this without needing anything 'static'. Namely, the flyweight pattern (for having only once instance) and lazy initialization (for doing work only once). Combine with factory as needed.
I'm having the same problem over and over again and it's hard for me to understand why Java 8 preferred to implement lambda instead of that.
Anyway, if your subclasses only implement retrieving a few parameters and doing rather simple tasks, you can use enumerations as they are very powerful in Java: you can basically consider it a fixed set of instances of an interface. They can have members, methods, etc. They just can't be instanciated (as they are "pre-instanciated").
public enum Processor {
PROC_IMAGE {
#Override
public String getParam() {
return "image";
}
},
PROC_TEXT {
#Override
public String getParam() {
return "text";
}
}
;
public abstract String getParam();
public boolean doProcessing() {
System.out.println(getParam());
}
}
The nice thing is that you can get all "instances" by calling Processor.values():
for (Processor p : Processorvalues()) {
System.out.println(String.format("Param %s: %s", p.name(), p.getParam()));
p.doProcessing();
}
If the processing is more complex, you can do it in other classes that are instanciated in the enum methods:
#Override
public String getParam() {
return new LookForParam("text").getParam();
}
You can then enrich the enumeration with any new processor you can think of.
The down side is that you can't use it if other people want to create new processors, as it means modifying the source file.
You can use the factory pattern to allow the system to create 'data' instances first, and create 'functional' instances later. The 'data' instances will contain the 'mandatory' getters that you wanted to have static. The 'functional' instances do complex parameter validation and/or expensive construction. Of course the parameter setter in the factory can also so preliminary validation.
public abstract class Processor { /*...*/ }
public interface ProcessorFactory {
String getName(); // The mandatory getter in this example
void setParameter(String parameter, String value);
/** #throws IllegalStateException when parameter validation fails */
Processor construct();
}
public class ProcessorA implements ProcessorFactory {
#Override
public String getName() { return "processor-a"; }
#Override
public void setParameter(String parameter, String value) {
Objects.requireNonNull(parameter, "parameter");
Objects.requireNonNull(value, "value");
switch (parameter) {
case "source": setSource(value); break;
/*...*/
default: throw new IllegalArgumentException("Unknown parameter: " + parameter);
}
}
private void setSource(String value) { /*...*/ }
#Override
public Processor construct() {
return new ProcessorAImpl();
}
// Doesn't have to be an inner class. It's up to you.
private class ProcessorAImpl extends Processor { /*...*/ }
}
I would like to implement a builder with a fluent interface.
Requirements
To make things more difficult there are two additional requirements:
I would like the returned objects to be immutable so that it can be used as follows and the interface should be extendible in derived interfaces:
ConcreteBuilder b1 = builder().setValue(1);
ConcreteBuilder b2 = b1.setValue(2);
ComplexObject o1 = b1.build();
o1.getValue(); // should return 1
ComplexObject o2 = b2.build();
o2.getValue(); // should return 2
First an issue open for discussion: should the builder be immutable so that it has above semantics? (it's briefly commented on by Jonathan in How to create an immutable builder of an immutable class that contains a set?)
The builder interface should be extendible:
interface Builder<T extends Builder<T>> {
T setValue(int v);
}
interfacte BuilderEx<T extends BuilderEx<T>> {
T someOtherOpp();
}
(it uses self referencing generics as described by Eamonn McManus1)
Implementation
To satisfy the first requirement AbstractBuilder's implementation is similar to the one in How to create an immutable builder of an immutable class that contains a set? :
class AbstractBuilder<T extends Builder<T>> implements Builder<T> {
T setValue(final int v) {
return castToConcrete(new AbstractBuilder<T>() {
// with build() overridden to use v
}
}
}
castToConcrete should be similar to self()1 and getThis()2: converting a Builder<T> to ConcreteBuilder or ConcreteBuilderEx depending on T . The problem is how to implement castToConcrete
Since the builder methods create new instances the method of overriding getThis in ConcreteBuilder doesn't work. Using a "functor"3 supplied to the constructor of AbstractBuilder and stored in a field enables conversion of Builder<T> to T. Add the following field (it uses the Guava library3 to AbstractBuilder:
Function<Builder<T>, T> castToConcrete;
Problem
My current implementation of castToConcrete turns quite ugly:
it's an if-else tree on instanceof
when input instanceof Builder and not input instanceof BuilderEx a wrapper class which needs to define all methods in BuilderEx, forward the ones in Builder to input and perform a default or nil operation for the others.
when input instanceof BuilderEx it casts input to ConcreteBuilderEx even though input is probably not an actual instance of ConcreteBuilderEx but an instance of an annonymous subclass of AbstractBuilderEx (hoping that this works.)[edit by OP]Doesn't work: we need a wrapper for every interface[/edit]
What is a better/cleaner way to do this?
The clean way is to not use an AbstractBuilder but create a specific builder for each type you need to build. You get a fluent interface by making builder methods readable and customized to the object you are trying to build. If you need to create lots of builders you can use code generation, but the methods won't be as well designed.
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