I want AspectJ to inject the measuring code around all invocations of any method, on fields annotated with #Measured and capture the method's name.
This is what I have:
#Pointcut("get(#my.annotation.Measured * *) && #annotation(measured)")
public void fieldAnnotatedWithMeasured(Measured measured) {}
#Around(value = "fieldAnnotatedWithMeasured(measured)", argNames = "joinPoint,measured")
public Object measureField(ProceedingJoinPoint joinPoint, Measured measured) throws Throwable {...}
Use case:
public class A {
#Measured private Service service;
...
void call(){
service.call(); // here I want to measure the call() time and capture its name
}
This seems to surround only the access to the field, not the method invocation. I want to capture the invoked method name instide the advise.
This is not something you can do directly with a pointcut because get(), as you have noticed, is entirely different from call() or execution() pointcuts. The get() joinpoint has completely passed before the moment the call() is done. Furthermore, the call() has no idea about whether or not the target object it is called upon happens to be assigned to one or more (annotated) class members.
I think that what you want to achieve is conceptually problematic. You should rather annotate the classes or methods you want to measure, not class members. But for what it is worth, I am going to present you with a solution. Caveat: The solution involves manual bookkeeping and also reflection. Thus, it is kinda slow but maybe still fast enough for your purpose. You can decide if you give it a try. Please note that this solution is something I feel uneasy with because it does not feel like a good application of AOP.
Okay, so here is our test setup:
Field annotation:
package de.scrum_master.app;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.FIELD)
public #interface Measured {}
Sample class to play around with later:
package de.scrum_master.app;
public class MyClass {
private String name;
public MyClass(String name) {
super();
this.name = name;
}
#Override
public String toString() {
return "MyClass[" + name + "]";
}
void waitForAWhile() throws InterruptedException {
Thread.sleep(200);
}
}
Driver application using the sample class:
Please note how only two of the four members - one primitive and one object type - are annotated by #Measured and two others are not. I did this in order to have positive as well as negative examples so as to see whether the aspect works correctly.
Another important thing is that an object formerly assigned to an annotated class member should no longer be reported by the aspect as soon as it is no longer assigned to that member. I.e. oldMyClass.waitForAWhile(); should not be measured.
package de.scrum_master.app;
public class Application {
String foo = "unmeasured";
#Measured String bar = "measured";
MyClass myClass1 = new MyClass("unmeasured");
#Measured MyClass myClass2 = new MyClass("measured");
void doSomething() throws InterruptedException {
foo.length();
bar.length();
myClass1.waitForAWhile();
myClass2.waitForAWhile();
MyClass oldMyClass = myClass2;
myClass2 = new MyClass("another measured");
// This call should not be reported by the aspect because the object
// is no longer assigned to a member annotated by #Measured
oldMyClass.waitForAWhile();
// This call should be reported for the new member value
myClass2.waitForAWhile();
}
public static void main(String[] args) throws InterruptedException {
new Application().doSomething();
}
}
Aspect:
The aspect takes care of two things: bookkeeping and measuring. In detail:
Whenever a value gets assigned to a #Measured field, it is recorded in a set of measuredObjects because this is the only way to later know that when a method is called on that object, it really should be measured.
While it is easy to get hold of the new value in a before() : set() advice, unfortunately there is no straightforward way to get hold of the old value. This is why we need the ugly little helper method getField(Signature signature) using reflection in order to find out.
Why do we need the old value anyway? Because in order to have clean bookkeeping we have to remove unassigned objects from the measuredObjects set.
Please also note that measuredObjects is not thread-safe the way I implemented it, but you can just use a synchronized collection if you need that.
The call() advice first checks if it can find the target object in measuredObjects and stops executing if it cannot. Otherwise it measures the method call's runtime. This is straightforward.
Oh, and by the way, I am using the cleaner and more expressive native AspectJ syntax here, not the ugly annotation style. If you have any problems with that, please let me know.
package de.scrum_master.app;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Set;
import org.aspectj.lang.Signature;
import org.aspectj.lang.SoftException;
import de.scrum_master.app.Measured;
public aspect MyAspect {
private Set<Object> measuredObjects = new HashSet<>();
before(Measured measured, Object newValue, Object object) :
set(* *) &&
#annotation(measured) &&
args(newValue) &&
target(object)
{
try {
Field field = getField(thisJoinPoint.getSignature());
Object oldValue = field.get(object);
System.out.println(thisJoinPoint);
System.out.println(" old value = " + oldValue);
System.out.println(" new value = " + newValue);
measuredObjects.remove(oldValue);
measuredObjects.add(newValue);
}
catch (Exception e) {
throw new SoftException(e);
}
}
Object around(Object object) :
call(* *(..)) &&
target(object) &&
!within(MyAspect)
{
if (!measuredObjects.contains(object))
return proceed(object);
long startTime = System.nanoTime();
Object result = proceed(object);
System.out.println(thisJoinPoint);
System.out.println(" object = " + object);
System.out.println(" duration = " + (System.nanoTime() - startTime) / 1e6 + " ms");
return result;
}
private Field getField(Signature signature) throws NoSuchFieldException {
Field field = signature.getDeclaringType().getDeclaredField(signature.getName());
field.setAccessible(true);
return field;
}
}
Console log:
set(String de.scrum_master.app.Application.bar)
old value = null
new value = measured
set(MyClass de.scrum_master.app.Application.myClass2)
old value = null
new value = MyClass[measured]
call(int java.lang.String.length())
object = measured
duration = 0.080457 ms
call(void de.scrum_master.app.MyClass.waitForAWhile())
object = MyClass[measured]
duration = 200.472326 ms
set(MyClass de.scrum_master.app.Application.myClass2)
old value = MyClass[measured]
new value = MyClass[another measured]
call(void de.scrum_master.app.MyClass.waitForAWhile())
object = MyClass[another measured]
duration = 200.461208 ms
As you can see, the aspect behaves correctly. It only reports the method call on object MyClass[measured] once, while it is assigned to a #Measured field, but not when a method is called upon it after it has already been unassigned and replaced by MyClass[another measured]. The latter is correctly reported subsequently. You also see how the aspect works beautifully even for primitives like the String "measured".
Enjoy!
Update 2021-04-22: I found this old answer again and wanted to mention a few other problems with the sample code, in addition to thread-unsafety:
The Set<Object> measuredObjects does not account for the fact that the same object can be assigned to multiple fields. If we want to consider that, we need to map a unique combination of instance and field to the corresponding value, i.e. we would need some kind of Map<Field,<Map<Object, Object>> where in the nested map the key is the instance (or the class name for static fields) and the value is the current field value. Managing this kind of data structure would be more complicated than the simple set we have now, especially if we also want to remove entries after a value is being unassigned.
Currently we use a simple HashSet. Actually, that is incorrect, because normal sets check for object value equality, not object identity. I.e. we could have conflicting instances a and b, where a.equals(b), but a != b. In order to fix that, we need an IdentitySet or, with the improvement I suggested in the first bullet point, an IdentityMap.
Considering the preceding two bullet points, probably a better alternative would be a dedicated class MeasuredEntity with fields Field field, Object instance, Object value and correctly defined equals and hashCode methods. then we could use a simple hash set again in order to do the bookkeeping.
Caveat: One problem cannot be solved by any kind of AspectJ-based bookeeping: If an object is currently assigned to any #Measured field, say A.x, then of course the measuring advice will get triggered if you call A.x.doSomething(). But there is no way of knowing if the same object is assigned to a non-measured field B.y or a local variable myLocal at the same time. So if B.y.doSomething() or myLocal.doSomething() are called, the measuring advice will also fire, which might be OK or unintended, depending on your individual situation. I think that it is no problem, you just need to be aware of it.
References to instances are not being removed from the set or map if an instance goes out of scope and would otherwise be eligible for garbage collection. In order to achieve that, we would need to use weak references.
A smaller issue is that getField(..) uses field.setAccessible(true). We might want to reset the field's accessible state after use in some kind of try {} finally {}, first storing the original value in a boolean variable, then resetting it in the finally block. But if that does not bother you, it really is just a small issue and also makes code execution a bit slower when called often.
Conclusion: Manual bookkeeping is not just complicated but in practice also poses several challenges which are difficult to fully meet. Not walking this path in the first place and changing the application design instead, so as to be able to apply aspects without recording internal object state, effectively breaking class encapsulation, is the better alternative IMO.
Related
I'm trying to write a class to take a mega object, and ensure that only certain fields have been changed, normally you would annotate / add validation this way, but that is not an option in this case unfortunately, the only thing I can change is the one class I am working on, which will receive the very large (and very nested!) object that I'm supposed to somehow validate.
My initial thoughts was to make a 'list' of things that can be changed, then iterate over all properties in the object and check if anything has been updated that is not on the 'whitelist', I have the old version of the object, so I can check each field against the old one to confirm, but I'm not entirely sure how to do this, or if there is a better solution. I've never tried something like this before.
Any suggestions are appreciated. If there aren't any better solutions, how should I create the white list / iterate over all properties / nested properties of the mega object?
UPDATE:
Based on the suggestions, here is what I'm trying out, it still have a few problems though (Please note I'm just throwing things around, this is by no means my final class or good programming yet):
isTraversable works on collections, but I'm not sure how to get check custom classes, eg. a Person class, which would still need to be iterated through.
There are cyclic refs all over the place, not sure how to handle those either.
public class Test {
private Object obj1;
private Object obj2;
private List<String> whitelist;
public void validate(Object objectToTraverse,
Object objectToCompareTo,
List<String> whitelist){
this.obj1 = objectToTraverse;
this.obj2 = objectToCompareTo;
this.whitelist = whitelist;
traverseAndCompare(obj1, obj2);
}
private void traverseAndCompare(Object objectToTraverse,
Object objectToCompareTo){
try {
for (Field field : objectToTraverse.getClass()
.getDeclaredFields()) {
field.setAccessible(true);
Object fieldValue = field.get(objectToTraverse);
if (isTraversable(field)) {
traverseAndCompare(field.get(objectToTraverse),
field.get(objectToCompareTo));
} else {
getFieldValuesAndCompare(field, obj1, obj2);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private boolean getFieldValuesAndCompare(Field field,
Object obj1,
Object obj2)
throws Exception{
Object value1 = field.get(obj1);
Object value2 = field.get(obj2);
return compare(value1, value2);
}
private boolean compare(Object value1,
Object value2){
return Objects.equals(value1, value2);
}
private boolean isTraversable(Field field){
// This should handle collections, but it does not work
// on custom classes, eg. Person class
if (Collection.class.isAssignableFrom(field.getType())) {
return true;
}
// Need to somehow figure out is this is a class with
// properties I can traverse, or something with a value,
// like String, Long, etc, hopefully
// without listing everything
return false;
}
}
Putting descriptive answer since object can not be shared due to legal reason.
You have couple of choices. Each with pro and con.
Reflection
You can maintain a list of fields not allowed to change with their full path. Like a.b.c. You can then write pure reflection code or use common utils like http://commons.apache.org/proper/commons-beanutils/ to get values (even deep in object tree) and compare.
It needs less code and less maintenance. But you need to know exact list of blacklist fields. Performance wise it will take little bit more time.
Simple plain code technique
Write your own comparator or method in java to go through all fields that can not change and decide. Need lot of code but very easy to maintain and performance wise best.
I saw some example of of using supplier interface at https://dzone.com/articles/supplier-interface.
My question is, if in the above example I could do something as easy as :
driveVehicle(new Vehicle());
driveVehicle(new Car());
Why would one want to use supplier interface, if all it does is call a method, without taking in any parameters.
Suppose you have parameters stored in database that you want to keep in constant all over your app
// Assume retrieveSystemParameter query database which allows to change parameters
public static String SYSTEM_PARAMETER = StaticUtilities.retrieveSystemParameter();
That value will be initialized once and won't change untill a redeployment. That being said, if instead you use a supplier :
public static Supplier<String> SYSTEM_PARAMETER_SUPPLIER = StaticUtilities::retrieveSystemParameter;
When you need the value somewhere you will call SYSTEM_PARAMETER_SUPPLIER.get() which will retrieve parameter in the database when needed - that way if you change a parameter in database, you won't have to redeploy.
As you can see, Suppliers are lazy. They do the work when you ask them to work (by calling .get()) - that may allow you some performance gain if you deal with them wisely. Sometimes you will call a method which expect a variable X passing in method retrieveX and then end up not needing X in the method because some conditions were not met. In that case you will lose performance as you will execute the code to retrieve X while a supplier that retrieve X would only execute it when calling .get and you would only do that call if the conditions were met.
Disclaimer : the system parameter constant is just the first example that came to my mind, but considering it query the database on each .get() you'd rather cache the parameter and have the cache call .get() at a specific interval.
I guess Optional might be perfect example. Consider the following snippet:
final Product firstProduct = Optional.ofNullable(product)
.orElse(productDao.findProductById(id));
final Product secondProduct = Optional.ofNullable(product)
.orElseGet(() -> productDao.findProductById(id));
You're getting a product that may be null. In order to determine firstProduct java will have to call expression in orElse method so no matter product is null or not you always have to determine value that will be returned in case product is null.
In order to determine secondProduct database doesn't have to be queried in case product is not null because you're passing a Supplier that will be called only if product is null.
Another example is when your method that accepts a supplier is not pure (i.e., it has side effect), and the side effect happens before calling the lambda, and the behaviour of the lambda is affected by the side effect.
Consider, for instance, this example:
public class TestClass {
private String field;
public String getField() {
return field;
}
public void method(Supplier<String> supplier) {
field = "This is";
System.out.println(supplier.get() + " a test");
}
public static void main(String[] args) {
TestClass c = new TestClass();
c.method(() -> c.getField());
}
}
Here, method() is not pure, as it changes the value of field, which is used later in the lambda (through calling the getField() method). As the lambda is called in place (i.e., when get() is called), calling getField() will happen after setting the field. In other words, method() accepts a Supplier<String> instead of a String in an attempt to let the clients safely call the getField() method.
Of course, having side effects should be avoided wherever possible, and this is just a toy example, but it shows a potential place where a supplier can be used.
Supplier adds one more level of indirection.
Given that "All problems in computer science can be solved by another level of indirection", it's likely that there are some problems that can be solved by using a Supplier.
Beware, however, of the corollary "...except for the problem of too many layers of indirection."
So, if there's no problem to solve, then Supplier is overkill and you should stick to directly invoking new.
Put differently: mistrust any "pattern" or "best practice" that doesn't start by explaining a problem (your question shows, you actually do mistrust, so just keep on asking this kind of questions).
I use it to avoid the unnecessary creation of additional states:
private Supplier<Boolean> detach = () -> false;
private Supplier<Boolean> isAttached = () -> false;
private Supplier<Integer> index = () -> null;
private final Function<List<ObserverWrapper<X, Y>>, Boolean> attachFun = observers -> {
isAttached = () -> observers.contains(this);
detach = () -> observers.remove(this);
index = () -> observers.indexOf(this);
return observers.add(this);
};
public boolean attach(List<ObserverWrapper<X, Y>> observers) {
return attachFun.apply(observers);
}
public boolean isAttached() {
return isAttached.get();
}
public Integer observerIndex() {
return index.get();
}
Which some would say is unnecessary in itself, but then it becomes a philosophical problem.
A problem which would not exist if computers didn't exist, and then it becomes a real world problem of indirection.
I may admit that suppliers for me may have become an addiction, but in my mind they feel like the natural extrapolation and extension of all the programming axioms and principles.
You could use a Supplier in a map based factory class
public class StackService {
final static String INTEGERS = "Integers";
final static String DOUBLES = "Doubles";
final static String STRINGS = "Strings";
final static Map<String, Supplier<Stack>> stackType;
static {
stackType = new HashMap<>();
stackType.put(INTEGERS, Stack<Integer>::new);
stackType.put(DOUBLES, Stack<Double>::new);
stackType.put(STRINGS, Stack<String>::new);
}
public Stack<?> createStackOfType(String stackType) {
return stackType.get(stackType).get();
}
}
Here if you were to just use new Stack() you would be returning a reference to the same object rather than a new one.
I provide an API and need to know, where methods of the API were invoked. I could of cause use reflection or the thread stacktrace, but that would include a lot of runtime cost.
I do not need the exact class name, a unique reference per invocation would be sufficient. In C I would normally use the preprocessor to automatically add __FILE__ and __LINE__ to the method invocation.
Is there a method in Java (besides code generation) to get a unique caller identification with low runtime cost?
One solution would be to have a cached Throwable which is passed in.
class StackPoint {
Throwable stack;
public Throwable getStack() {
if (stack == null)
stack = new Throwable();
return stack;
}
}
public void methodToCall(StackPoint sp) {
Throwable t = sp.getStack();
}
static final StackPoint one = new StackPoint();
methodToCall(one); // Have to remember to give each line a different StackPoint.
Note: if the method which calls this caller changes, you only record the first one ever.
There isn't a standard pattern and it is likely that if you want this to be efficient the caller will need to pass a unique id. The closest you can do is use is a lambda.
public void methodToCall(Runnable run) {
Class id = run.getClass();
}
You can call it like this
methodtoCall(()->{});
This will create a different class for each place it is called, even if it appears multiple times on the same line. It creates no garbage as it reuses the same object each time. You could make this shorter with
void methodToCall(IntFunction fun) {
}
and call
methodToCall(a->1);
As something asynchroneous is involved, split the call up, and let the API return the ID.
Ticket callTicket = api.call(params);
Logger.getLogger(getClass().getName(), Level.FINE, callTicket);
Result result = callTicket.get();
Above having a result returned (synchroneously) is probably not the case with your code. Your code will get the result delived elsewhere. But that could be a ticket system too.
I would like to do dynamic casting for a Java variable, the casting type is stored in a different variable.
This is the regular casting:
String a = (String) 5;
This is what I want:
String theType = 'String';
String a = (theType) 5;
Is this possible, and if so how? Thanks!
Update
I'm trying to populate a class with a HashMap that I received.
This is the constructor:
public ConnectParams(HashMap<String,Object> obj) {
for (Map.Entry<String, Object> entry : obj.entrySet()) {
try {
Field f = this.getClass().getField(entry.getKey());
f.set(this, entry.getValue()); /* <= CASTING PROBLEM */
} catch (NoSuchFieldException ex) {
log.error("did not find field '" + entry.getKey() + '"');
} catch (IllegalAccessException ex) {
log.error(ex.getMessage());
}
}
}
The problem here is that some of the class' variables are of type Double, and if the number 3 is received it sees it as Integer and I have type problem.
Yes it is possible using Reflection
Object something = "something";
String theType = "java.lang.String";
Class<?> theClass = Class.forName(theType);
Object obj = theClass.cast(something);
but that doesn't make much sense since the resulting object must be saved in a variable of Object type. If you need the variable be of a given class, you can just cast to that class.
If you want to obtain a given class, Number for example:
Object something = new Integer(123);
String theType = "java.lang.Number";
Class<? extends Number> theClass = Class.forName(theType).asSubclass(Number.class);
Number obj = theClass.cast(something);
but there is still no point doing it so, you could just cast to Number.
Casting of an object does NOT change anything; it is just the way the compiler treats it.
The only reason to do something like that is to check if the object is an instance of the given class or of any subclass of it, but that would be better done using instanceof or Class.isInstance().
Update
according your last update the real problem is that you have an Integer in your HashMap that should be assigned to a Double. What you can do in this case, is check the type of the field and use the xxxValue() methods of Number
...
Field f = this.getClass().getField(entry.getKey());
Object value = entry.getValue();
if (Integer.class.isAssignableFrom(f.getType())) {
value = Integer.valueOf(((Number) entry.getValue()).intValue());
} else if (Double.class.isAssignableFrom(f.getType())) {
value = Double.valueOf(((Number) entry.getValue()).doubleValue());
} // other cases as needed (Long, Float, ...)
f.set(this, value);
...
(not sure if I like the idea of having the wrong type in the Map)
You'll need to write sort of ObjectConverter for this. This is doable if you have both the object which you want to convert and you know the target class to which you'd like to convert to. In this particular case you can get the target class by Field#getDeclaringClass().
You can find here an example of such an ObjectConverter. It should give you the base idea. If you want more conversion possibilities, just add more methods to it with the desired argument and return type.
Regarding your update, the only way to solve this in Java is to write code that covers all cases with lots of if and else and instanceof expressions. What you attempt to do looks as if are used to program with dynamic languages. In static languages, what you attempt to do is almost impossible and one would probably choose a totally different approach for what you attempt to do. Static languages are just not as flexible as dynamic ones :)
Good examples of Java best practice are the answer by BalusC (ie ObjectConverter) and the answer by Andreas_D (ie Adapter) below.
That does not make sense, in
String a = (theType) 5;
the type of a is statically bound to be String so it does not make any sense to have a dynamic cast to this static type.
PS: The first line of your example could be written as Class<String> stringClass = String.class; but still, you cannot use stringClass to cast variables.
You can do this using the Class.cast() method, which dynamically casts the supplied parameter to the type of the class instance you have. To get the class instance of a particular field, you use the getType() method on the field in question. I've given an example below, but note that it omits all error handling and shouldn't be used unmodified.
public class Test {
public String var1;
public Integer var2;
}
public class Main {
public static void main(String[] args) throws Exception {
Map<String, Object> map = new HashMap<String, Object>();
map.put("var1", "test");
map.put("var2", 1);
Test t = new Test();
for (Map.Entry<String, Object> entry : map.entrySet()) {
Field f = Test.class.getField(entry.getKey());
f.set(t, f.getType().cast(entry.getValue()));
}
System.out.println(t.var1);
System.out.println(t.var2);
}
}
You can write a simple castMethod like the one below.
private <T> T castObject(Class<T> clazz, Object object) {
return (T) object;
}
In your method you should be using it like
public ConnectParams(HashMap<String,Object> object) {
for (Map.Entry<String, Object> entry : object.entrySet()) {
try {
Field f = this.getClass().getField(entry.getKey());
f.set(this, castObject(entry.getValue().getClass(), entry.getValue()); /* <= CASTING PROBLEM */
} catch (NoSuchFieldException ex) {
log.error("did not find field '" + entry.getKey() + '"');
} catch (IllegalAccessException ex) {
log.error(ex.getMessage());
}
}
}
It works and there's even a common pattern for your approach: the Adapter pattern. But of course, (1) it does not work for casting java primitives to objects and (2) the class has to be adaptable (usually by implementing a custom interface).
With this pattern you could do something like:
Wolf bigBadWolf = new Wolf();
Sheep sheep = (Sheep) bigBadWolf.getAdapter(Sheep.class);
and the getAdapter method in Wolf class:
public Object getAdapter(Class clazz) {
if (clazz.equals(Sheep.class)) {
// return a Sheep implementation
return getWolfDressedAsSheep(this);
}
if (clazz.equals(String.class)) {
// return a String
return this.getName();
}
return null; // not adaptable
}
For you special idea - that is impossible. You can't use a String value for casting.
Your problem is not the lack of "dynamic casting". Casting Integer to Double isn't possible at all. You seem to want to give Java an object of one type, a field of a possibly incompatible type, and have it somehow automatically figure out how to convert between the types.
This kind of thing is anathema to a strongly typed language like Java, and IMO for very good reasons.
What are you actually trying to do? All that use of reflection looks pretty fishy.
Don't do this. Just have a properly parameterized constructor instead. The set and types of the connection parameters are fixed anyway, so there is no point in doing this all dynamically.
For what it is worth, most scripting languages (like Perl) and non-static compile-time languages (like Pick) support automatic run-time dynamic String to (relatively arbitrary) object conversions. This CAN be accomplished in Java as well without losing type-safety and the good stuff statically-typed languages provide WITHOUT the nasty side-effects of some of the other languages that do evil things with dynamic casting. A Perl example that does some questionable math:
print ++($foo = '99'); # prints '100'
print ++($foo = 'a0'); # prints 'a1'
In Java, this is better accomplished (IMHO) by using a method I call "cross-casting".
With cross-casting, reflection is used in a lazy-loaded cache of constructors and methods that are dynamically discovered via the following static method:
Object fromString (String value, Class targetClass)
Unfortunately, no built-in Java methods such as Class.cast() will do this for String to BigDecimal or String to Integer or any other conversion where there is no supporting class hierarchy. For my part, the point is to provide a fully dynamic way to achieve this - for which I don't think the prior reference is the right approach - having to code every conversion. Simply put, the implementation is just to cast-from-string if it is legal/possible.
So the solution is simple reflection looking for public Members of either:
STRING_CLASS_ARRAY = (new Class[] {String.class});
a) Member member = targetClass.getMethod(method.getName(),STRING_CLASS_ARRAY);
b) Member member = targetClass.getConstructor(STRING_CLASS_ARRAY);
You will find that all of the primitives (Integer, Long, etc) and all of the basics (BigInteger, BigDecimal, etc) and even java.regex.Pattern are all covered via this approach. I have used this with significant success on production projects where there are a huge amount of arbitrary String value inputs where some more strict checking was needed. In this approach, if there is no method or when the method is invoked an exception is thrown (because it is an illegal value such as a non-numeric input to a BigDecimal or illegal RegEx for a Pattern), that provides the checking specific to the target class inherent logic.
There are some downsides to this:
1) You need to understand reflection well (this is a little complicated and not for novices).
2) Some of the Java classes and indeed 3rd-party libraries are (surprise) not coded properly. That is, there are methods that take a single string argument as input and return an instance of the target class but it isn't what you think... Consider the Integer class:
static Integer getInteger(String nm)
Determines the integer value of the system property with the specified name.
The above method really has nothing to do with Integers as objects wrapping primitives ints.
Reflection will find this as a possible candidate for creating an Integer from a String incorrectly versus the decode, valueof and constructor Members - which are all suitable for most arbitrary String conversions where you really don't have control over your input data but just want to know if it is possible an Integer.
To remedy the above, looking for methods that throw Exceptions is a good start because invalid input values that create instances of such objects should throw an Exception. Unfortunately, implementations vary as to whether the Exceptions are declared as checked or not. Integer.valueOf(String) throws a checked NumberFormatException for example, but Pattern.compile() exceptions are not found during reflection lookups. Again, not a failing of this dynamic "cross-casting" approach I think so much as a very non-standard implementation for exception declarations in object creation methods.
If anyone would like more details on how the above was implemented, let me know but I think this solution is much more flexible/extensible and with less code without losing the good parts of type-safety. Of course it is always best to "know thy data" but as many of us find, we are sometimes only recipients of unmanaged content and have to do the best we can to use it properly.
Cheers.
So, this is an old post, however I think I can contribute something to it.
You can always do something like this:
package com.dyna.test;
import java.io.File;
import java.lang.reflect.Constructor;
public class DynamicClass{
#SuppressWarnings("unchecked")
public Object castDynamicClass(String className, String value){
Class<?> dynamicClass;
try
{
//We get the actual .class object associated with the specified name
dynamicClass = Class.forName(className);
/* We get the constructor that received only
a String as a parameter, since the value to be used is a String, but we could
easily change this to be "dynamic" as well, getting the Constructor signature from
the same datasource we get the values from */
Constructor<?> cons =
(Constructor<?>) dynamicClass.getConstructor(new Class<?>[]{String.class});
/*We generate our object, without knowing until runtime
what type it will be, and we place it in an Object as
any Java object extends the Object class) */
Object object = (Object) cons.newInstance(new Object[]{value});
return object;
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
public static void main(String[] args)
{
DynamicClass dynaClass = new DynamicClass();
/*
We specify the type of class that should be used to represent
the value "3.0", in this case a Double. Both these parameters
you can get from a file, or a network stream for example. */
System.out.println(dynaClass.castDynamicClass("java.lang.Double", "3.0"));
/*
We specify a different value and type, and it will work as
expected, printing 3.0 in the above case and the test path in the one below, as the Double.toString() and
File.toString() would do. */
System.out.println(dynaClass.castDynamicClass("java.io.File", "C:\\testpath"));
}
Of course, this is not really dynamic casting, as in other languages (Python for example), because java is a statically typed lang. However, this can solve some fringe cases where you actually need to load some data in different ways, depending on some identifier. Also, the part where you get a constructor with a String parameter could be probably made more flexible, by having that parameter passed from the same data source. I.e. from a file, you get the constructor signature you want to use, and the list of values to be used, that way you pair up, say, the first parameter is a String, with the first object, casting it as a String, next object is an Integer, etc, but somehwere along the execution of your program, you get now a File object first, then a Double, etc.
In this way, you can account for those cases, and make a somewhat "dynamic" casting on-the-fly.
Hope this helps anyone as this keeps turning up in Google searches.
Try this for Dynamic Casting. It will work!!!
String something = "1234";
String theType = "java.lang.Integer";
Class<?> theClass = Class.forName(theType);
Constructor<?> cons = theClass.getConstructor(String.class);
Object ob = cons.newInstance(something);
System.out.println(ob.equals(1234));
I recently felt like I had to do this too, but then found another way which possibly makes my code look neater, and uses better OOP.
I have many sibling classes that each implement a certain method doSomething(). In order to access that method, I would have to have an instance of that class first, but I created a superclass for all my sibling classes and now I can access the method from the superclass.
Below I show two ways alternative ways to "dynamic casting".
// Method 1.
mFragment = getFragmentManager().findFragmentByTag(MyHelper.getName(mUnitNum));
switch (mUnitNum) {
case 0:
((MyFragment0) mFragment).sortNames(sortOptionNum);
break;
case 1:
((MyFragment1) mFragment).sortNames(sortOptionNum);
break;
case 2:
((MyFragment2) mFragment).sortNames(sortOptionNum);
break;
}
and my currently used method,
// Method 2.
mSuperFragment = (MySuperFragment) getFragmentManager().findFragmentByTag(MyHelper.getName(mUnitNum));
mSuperFragment.sortNames(sortOptionNum);
Just thought I would post something that I found quite useful and could be possible for someone who experiences similar needs.
The following method was a method I wrote for my JavaFX application to avoid having to cast and also avoid writing if object x instance of object b statements every time the controller was returned.
public <U> Optional<U> getController(Class<U> castKlazz){
try {
return Optional.of(fxmlLoader.<U>getController());
}catch (Exception e){
e.printStackTrace();
}
return Optional.empty();
}
The method declaration for obtaining the controller was
public <T> T getController()
By using type U passed into my method via the class object, it could be forwarded to the method get controller to tell it what type of object to return. An optional object is returned in case the wrong class is supplied and an exception occurs in which case an empty optional will be returned which we can check for.
This is what the final call to the method looked like (if present of the optional object returned takes a Consumer
getController(LoadController.class).ifPresent(controller->controller.onNotifyComplete());
So, I have willfully kept myself a Java n00b until recently, and my first real exposure brought about a minor shock: Java does not have C# style properties!
Ok, I can live with that. However, I can also swear that I have seen property getter/setter code in Java in one codebase, but I cannot remember where. How was that achieved? Is there a language extension for that? Is it related to NetBeans or something?
There is a "standard" pattern for getters and setters in Java, called Bean properties. Basically any method starting with get, taking no arguments and returning a value, is a property getter for a property named as the rest of the method name (with a lowercased start letter). Likewise set creates a setter of a void method with a single argument.
For example:
// Getter for "awesomeString"
public String getAwesomeString() {
return awesomeString;
}
// Setter for "awesomeString"
public void setAwesomeString( String awesomeString ) {
this.awesomeString = awesomeString;
}
Most Java IDEs will generate these methods for you if you ask them (in Eclipse it's as simple as moving the cursor to a field and hitting Ctrl-1, then selecting the option from the list).
For what it's worth, for readability you can actually use is and has in place of get for boolean-type properties too, as in:
public boolean isAwesome();
public boolean hasAwesomeStuff();
I am surprised that no one mentioned project lombok
Yes, currently there are no properties in java. There are some other missing features as well.
But luckily we have project lombok that is trying to improve the situation. It is also getting more and more popular every day.
So, if you're using lombok:
#Getter #Setter int awesomeInteger = 5;
This code is going to generate getAwesomeInteger and setAwesomeInteger as well. So it is quite similar to C# auto-implemented properties.
You can get more info about lombok getters and setters here.
You should definitely check out other features as well.
My favorites are:
val
NoArgsConstructor, RequiredArgsConstructor, AllArgsConstructor
Logs!
Lombok is well-integrated with IDEs, so it is going to show generated methods like if they existed (suggestions, class contents, go to declaration and refactoring).
The only problem with lombok is that other programmers might not know about it. You can always delombok the code but that is rather a workaround than a solution.
"Java Property Support" was proposed for Java 7, but did not make it into the language.
See http://tech.puredanger.com/java7#property for more links and info, if interested.
The bean convention is to write code like this:
private int foo;
public int getFoo() {
return foo;
}
public void setFoo(int newFoo) {
foo = newFoo;
}
In some of the other languages on the JVM, e.g., Groovy, you get overridable properties similar to C#, e.g.,
int foo
which is accessed with a simple .foo and leverages default getFoo and setFoo implementations that you can override as necessary.
public class Animal {
#Getter #Setter private String name;
#Getter #Setter private String gender;
#Getter #Setter private String species;
}
This is something like C# properties. It's http://projectlombok.org/
You may not need for "get" and "set" prefixes, to make it look more like properties, you may do it like this:
public class Person {
private String firstName = "";
private Integer age = 0;
public String firstName() { return firstName; } // getter
public void firstName(String val) { firstName = val; } // setter
public Integer age() { return age; } // getter
public void age(Integer val) { age = val; } //setter
public static void main(String[] args) {
Person p = new Person();
//set
p.firstName("Lemuel");
p.age(40);
//get
System.out.println(String.format("I'm %s, %d yearsold",
p.firstName(),
p.age());
}
}
Most IDEs for Java will automatically generate getter and setter code for you if you want them to. There are a number of different conventions, and an IDE like Eclipse will allow you to choose which one you want to use, and even let you define your own.
Eclipse even includes automated refactoring that will allow you to wrap a property up in a getter and setter and it will modify all the code that accesses the property directly, to make it use the getter and/or setter.
Of course, Eclipse can only modify code that it knows about - any external dependencies you have could be broken by such a refactoring.
My Java experience is not that high either, so anyone feel free to correct me. But AFAIK, the general convention is to write two methods like so:
public string getMyString() {
// return it here
}
public void setMyString(string myString) {
// set it here
}
From Jeffrey Richter's book CLR via C#: (I think these might be the reasons why properties are still not added in JAVA)
A property method may throw an exception; field access never throws an exception.
A property cannot be passed as an out or ref parameter to a method; a field can.
A property method can take a long time to execute; field access always completes
immediately. A common reason to use properties is to perform thread synchronization,
which can stop the thread forever, and therefore, a property should not be
used if thread synchronization is required. In that situation, a method is preferred.
Also, if your class can be accessed remotely (for example, your class is derived from
System.MarshalByRefObject), calling the property method will be very slow, and
therefore, a method is preferred to a property. In my opinion, classes derived from
MarshalByRefObject should never use properties.
If called multiple times in a row, a property method may return a different value each
time; a field returns the same value each time. The System.DateTime class has a readonly
Now property that returns the current date and time. Each time you query this
property, it will return a different value. This is a mistake, and Microsoft wishes that
they could fix the class by making Now a method instead of a property. Environment’s
TickCount property is another example of this mistake.
A property method may cause observable side effects; field access never does. In other
words, a user of a type should be able to set various properties defined by a type in
any order he or she chooses without noticing any different behavior in the type.
A property method may require additional memory or return a reference to something
that is not actually part of the object’s state, so modifying the returned object has no
effect on the original object; querying a field always returns a reference to an object
that is guaranteed to be part of the original object’s state. Working with a property
that returns a copy can be very confusing to developers, and this characteristic is frequently
not documented.
If you're using eclipse then it has the capabilities to auto generate the getter and setter method for the internal attributes, it can be a usefull and timesaving tool.
I'm just releasing Java 5/6 annotations and an annotation processor to help this.
Check out http://code.google.com/p/javadude/wiki/Annotations
The documentation is a bit light right now, but the quickref should get the idea across.
Basically it generates a superclass with the getters/setters (and many other code generation options).
A sample class might look like
#Bean(properties = {
#Property(name="name", bound=true),
#Property(name="age,type=int.class)
})
public class Person extends PersonGen {
}
There are many more samples available, and there are no runtime dependencies in the generated code.
Send me an email if you try it out and find it useful!
-- Scott
There is no property keyword in java (like you could find it in C#) the nearest way to have 1 word getter/setter is to do like in C++:
public class MyClass
{
private int aMyAttribute;
public MyClass()
{
this.aMyAttribute = 0;
}
public void mMyAttribute(int pMyAttributeParameter)
{
this.aMyAttribute = pMyAttributeParameter;
}
public int mMyAttribute()
{
return this.aMyAttribute;
}
}
//usage :
int vIndex = 1;
MyClass vClass = new MyClass();
vClass.mMyAttribute(vIndex);
vIndex = 0;
vIndex = vClass.mMyAttribute();
// vIndex == 1
As previously mentioned for eclipse, integrated development environment (IDE) often can create accessor methods automatically.
You can also do it using NetBeans.
To create accessor methods for your class, open a class file, then Right-click anywhere in the source code editor and choose the menu command Refactor, Encapsulate Fields.
A dialog opens. Click Select All, then click Refactor.
Voilà,
Good luck,
For me the problem is two fold:
All these extra methods {get*/set*} cluttering up the class code.
NOT being able to treat them like properties:
public class Test {
private String _testField;
public String testProperty {
get {
return _testField;
}
set {
_testField = value;
}
}
}
public class TestUser {
private Test test;
public TestUser() {
test = new Test();
test.testProperty = "Just something to store";
System.out.printLn(test.testProperty);
}
}
This is the sort of easy assignment I would like to get back to using. NOT having to use 'method' calling syntax. Can anyone provide some answers as to what happened to Java?
I think that the issue is also about the unnecessary clutter in the code, and not the 'difficulty' of creating the setters/getters. I consider them as ugly-code. I like what C# has. I don't understand the resistance to adding that capability to Java.
My current solution is to use 'public' members when protection is not required:
public class IntReturn {
public int val;
}
public class StringReturn {
public String val;
}
These would be used to return value from say a Lambda:
StringReturn sRtn = new StringReturn()
if(add(2, 3, sRtn)){
System.out.println("Value greater than zero");
}
public boolean add(final int a, final int b, final StringReturn sRtn){
int rtn = a + b;
sRtn.val = "" + rtn;
return rtn > 0; // Just something to use the return for.
}
I also really don't like using a method call to set or get an internal value from a class.
If your information is being transferred as 'immutable', then the new Java record could be a solution. However, it still uses the setter/getter methodology, just without the set/get prefixes.