Passing a class ("Country.class") as an argument in Java - java

I'm trying to make a method that takes an argument of Country.class, User.class etc, and returns argument.count().
All the possible classes that I would give to this method extend from Model and have the method count().
My code:
private static long <T> countModel(Model<T> clazz)
{
// there is other important stuff here, which prevents me from
// simply by-passing the method altogether.
return clazz.count();
}
Called by:
renderArgs.put("countryCount", countModel(Country.class));
However this just doesn't work at all.
How do I do this, please?

I think you want to do
private long countModel(Class<? extends Model> clazz) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException
{
Method countMethod = clazz.getDeclaredMethod("count", null);
return (Long) countMethod.invoke(null, null);
}
Hopefully something like this would work (my reflection skills are not really that good).

Don't fully understand what you are trying to achieve. Did you mean this?
private static long <T> countModel(Model<T> model)
{
return model.count();
}
renderArgs.put("countryCount", countModel(country));
EDIT: If count is a static method, it has nothing to do with model. The static method is not inherited. So all you have to do is to call it directly,
renderArgs.put("countryCount", Country.count());

Clarifying, you want a class (A) that is constrained to have a particular class method (B) and you want to pass that class as an argument to some other method (C) and have that method (C) invoke that class method on that class (A.B())?
The first part, the type constraint, that can't be done. Java's type system just does not work that way.
The second part, passing a class as an argument and invoking a class method on it, that can be done using reflection. This is how to do it, correcting from your code (though you should be more careful with the exceptions than I've been in this).
private static <T extends Model> long countModel(Class<T> clazz) throws Exception
{
return (Long) clazz.getMethod("count").invoke(null);
}
The null is the instance to invoke this on (no instance; it's a class method). The cast to Long is required as the result of invoke() is an Object. The type parameter must go before the result type. And the whole thing can take any class that is a subclass of Model as a parameter; it will just fail at runtime if the count method isn't present. Them's the breaks.
(Also note that if you wanted to pass arguments to count(), you'd have to specify the classes of those arguments to getMethod and the values themselves to invoke, in both cases as subsequent arguments. Both support Java5 variable argument lists.)

In the line
renderArgs.put("countryCount", countModel(Country.class));
you call countModel with a Class<Country>, but you have to call it with an instance of Country like this:
Country country = new Country();
renderArgs.put("countryCount", countModel( country );

In reply to your comment to ZZ Coder; a static method in Java is called in the namespace context of a class, like Model.count() for a static method count() in the class Model, but the method does not become part of Model.class, Model.class is an instance of Class describing the class Model. (I can see where the confusion originates, it would be logical to have a specialised Model.class that includes the static methods, but Java isn't desinged that way.)
Your way out is to use reflection to call the static count() for the class that you pass to your code.

You are not passing an instance of country here, you are passing a Class object:
renderArgs.put("countryCount", countModel(Country.class));
You need to instantiate A model and pass it as an argument:
Model model = new Country();
renderArgs.put("countryCount", countModel(model));
or
Country country = new Country();
renderArgs.put("countryCount", countModel(country));
In this case, Country.class is an object of the Class<Country> type.

You are passing Country.class which is a Class object. How is it a Model object?

Related

Java How to avoid passing Class as parameter of generic object

I have written the following:
public class DataContainer<Data>{
public DataContainer(Class<Data> clazz, String method) throws NoSuchMethodException, SecurityException{
clazz.getMethod(method);
}
}
And so I create my objects this way:
new DataContainer<SomeClass>(SomeClass.class, "get");
But I wanted it to look more like:
public class DataContainer<Data>{
public DataContainer(String method) throws NoSuchMethodException, SecurityException{
Data.getMethod(method);
}
}
And a construct call should look like this:
new DataContainer<SomeClass>("get");
How can I avoid passing the Data class when I construct A DataContainer object? I know Data can't be manipulated at runtime (new DataContainer<>("get"); -> what is Data then?) but I've heard there are solutions to work around, unfortunately it seems like I haven't the vocab yet to google it.
Also it's a simplified version of my problem, we assume method is valid, public and hasn't arguments.
It's not really possible in the way you want to use your code, due to type erasure.
However, some generic information is preserved at runtime, i.e. when it is accessible to reflection. One such situation would be generics on the class hierarchy, i.e. you could do something like this (which we do quite frequently):
//Note that I used T instead of Data to reduce confusion
//Data looks a lot like an actual class name
public abstract class DataContainer<T>{
public DataContainer(String method) throws NoSuchMethodException, SecurityException {
Class<?> actualClass = getActualTypeForT();
//use reflection to get the method from actualClass and call it
}
protected Class<?> getActualTypeForT() {
//get the generic boundary here, for details check http://www.artima.com/weblogs/viewpost.jsp?thread=208860
}
}
//A concrete subclass to provide the actual type of T for reflection, can be mostly empty
public class SomeClassContainer extends DataContainer<SomeClass> {
//constructor etc.
}
Something similar should be possible for class fields or parameters, although I didn't test that.

How can I pass parameter class name in generic constructor

public class RestResponseDTO<T extends Object> {
private T result;
}
code where I am initializing this:
public RestResponseDTO getObject(String url,Class clz){
Class cv = clz.getClass();
RestResponseDTO<cv> restResponseDTO =restTemplate.getForObject(url,RestResponseDTO.class);
return restResponseDTO;
}
How can I initalize RestResponseDTO in my getObject function depending upon the clz type?
ps- getForObject is spring restTemplate's standard function- http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html#getForObject-java.lang.String-java.lang.Class-java.lang.Object...-
You can add method like this:
void init(Class clazz) {
//you initializing logic
}
and call it
RestResponseDTO<cv> restResponseDTO =restTemplate.getForObject(url,RestResponseDTO.class);
restResponseDTO.init(clz);
return restResponseDTO;
PS: Your cv variable will always have same value.
Please try:
ResponseEntity responseEntity = restTemplate.getForObject(url,RestResponseDTO.class);
and
responseEntity.getBody()
will give you Object T.
You can not pass a class with generic parameter to a method that has the parametertype Class<?>, you need something like Type.
One way (the only i am aware of) around is: create a concrete type that includes the generic parameter.
class IntegerResponse extends RestResponse<Integer>{
...
}
That way you can pass IntegerResponse.class

Java - Factory Method that returns generic Base type

I'm trying to genericize a factory method that returns
a generic Base class. It works, but I'm getting the
"BaseClass is a raw type..." warning.
I've read through the Java docs on Generic methods,
but I'm still not quite getting how to accomplish this.
Here's some code:
Class #1
//base abstract class
public abstract class BaseFormatter<T>
{
public abstract String formatValue(T value);
}
Class #2
//two implementations of concrete classes
public class FooFormatter extends BaseFormatter<Integer>
{
#Override
public String formatValue(Integer value)
{
//return a formatted String
}
}
Class #3
public class BarFormatter extends BaseFormatter<String>
{
#Override
public String formatValue(String value)
{
//return a formatted String
}
}
Factory Method in a separate class
public static BaseFormatter getFormatter(Integer unrelatedInteger)
{
if (FOO_FORMATTER.equals(unrelatedInteger))
return new FooFormatter();
else if (BAR_FORMATTER.equals(unrelatedInteger))
return new BarFormatter();
//else...
}
Call to the Factory Method from elsewhere in the code
BaseFormatter<Integer> formatter = getFormatter(someInteger);
formatter.formatValue(myIntegerToFormat);
The problem is the getFormatter() method warns that BaseFormatter is
a raw type, which it is. I've tried various things like BaseFormatter
et al. I, of course, want the return type to be generic, as in the declared
BaseFormatter in the calling method.
Note that the formatter type is not based on class type. e.g. not all Integer
values are formatted with a FooFormatter. There are two or three different
ways an Integer (or String, or List) can be formatted. That's what the
param unrelatedInteger is for.
Thanks in advance for any feedback.
If getFormatter is defined in BaseFormatter, then use:
public static BaseFormatter<T> getFormatter(Integer unrelatedInteger)
If getFormatter is defined in another class than BaseFormatter, then use:
public static BaseFormatter<?> getFormatter(Integer unrelatedInteger)
You're actuaaly saying that there's no connection between the typed parameter of BaseFormatter and the unrelatedInteger that is passed as argument to the getFormatter method.
I get some other warning:
Uncehcked Assignment: BaseFormatter to BaseFormatter<Integer>
This warning is worse than the one you indicated. It warns that this user code might try to insert a BaseFormatter<String> into BaseFormatter<Integer>, something that will be noticed only when fails in runtime... Consider a user accidentally uses you factory method like such:
BaseFormatter<Integer> myUnsafeFormatter =
FormatterFactory.getFormatter(unrelatedIntegerForBarFormatter);
The compiler cannot relate the unrelatedInteger with the parameterized type of the returned BaseFormatter.
Alternitavely, I'd let the user explicitly use the concrete formatter constructors. Any common code shared by all formatters could be put into FormatterUtils class (just don't let that utils class to grow to much...).
Some type systems in academic languages can express a so-called dependent sum. Java certainly cannot; so what, sensibly, could be the type of the object returned by the getFormatter method? The best we can do is BaseFormatter< ? extends Object >, or BaseFormatter< ? > for short, as Integer and String have only Object in common.
I think the original post begs the question, why must we use an integer to decide what formatter to return, and if the type of formatter would not be known by the caller, why would the caller need a stronger variable type than BaseFormatter< ? >?

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

Type-safe method reflection in Java

Is any practical way to reference a method on a class in a type-safe manner? A basic example is if I wanted to create something like the following utility function:
public Result validateField(Object data, String fieldName,
ValidationOptions options) { ... }
In order to call it, I would have to do:
validateField(data, "phoneNumber", options);
Which forces me to either use a magic string, or declare a constant somewhere with that string.
I'm pretty sure there's no way to get around that with the stock Java language, but is there some kind of (production grade) pre-compiler or alternative compiler that may offer a work around? (similar to how AspectJ extends the Java language) It would be nice to do something like the following instead:
public Result validateField(Object data, Method method,
ValidationOptions options) { ... }
And call it with:
validateField(data, Person.phoneNumber.getter, options);
As others mention, there is no real way to do this... and I've not seen a precompiler that supports it. The syntax would be interesting, to say the least. Even in your example, it could only cover a small subset of the potential reflective possibilities that a user might want to do since it won't handle non-standard accessors or methods that take arguments, etc..
Even if it's impossible to check at compile time, if you want bad code to fail as soon as possible then one approach is to resolve referenced Method objects at class initialization time.
Imagine you have a utility method for looking up Method objects that maybe throws error or runtime exception:
public static Method lookupMethod( Class c, String name, Class... args ) {
// do the lookup or throw an unchecked exception of some kind with a really
// good error message
}
Then in your classes, have constants to preresolve the methods you will use:
public class MyClass {
private static final Method GET_PHONE_NUM = MyUtils.lookupMethod( PhoneNumber.class, "getPhoneNumber" );
....
public void someMethod() {
validateField(data, GET_PHONE_NUM, options);
}
}
At least then it will fail as soon as MyClass is loaded the first time.
I use reflection a lot, especially bean property reflection and I've just gotten used to late exceptions at runtime. But that style of bean code tends to error late for all kinds of other reasons, being very dynamic and all. For something in between, the above would help.
There isn't anything in the language yet - but part of the closures proposal for Java 7 includes method literals, I believe.
I don't have any suggestions beyond that, I'm afraid.
Check out https://proxetta.jodd.org/refs/methref. It uses the Jodd proxy library (Proxetta) to proxy your type. Not sure about its performance characteristics, but it does provide type safety.
An example: Suppose Str.class has method .boo(), and you want to get its name as the string "boo":
String methodName = Methref.of(Str.class).name(Str::boo);
There's more to the API than the example above: https://oblac.github.io/jodd-site/javadoc/jodd/methref/Methref.html
Is any practical way to reference a method on a class in a type-safe manner?
First of all, reflection is type-safe. It is just that it is dynamically typed, not statically typed.
So, assuming that you want a statically typed equivalent of reflection, the theoretical answer is that it is impossible. Consider this:
Method m;
if (arbitraryFunction(obj)) {
m = obj.getClass().getDeclaredMethod("foo", ...);
} else {
m = obj.getClass().getDeclaredMethod("bar", ...);
}
Can we do this so that that runtime type exceptions cannot happen? In general NO, since this would entail proving that arbitraryFunction(obj) terminates. (This is equivalent to the Halting Problem, which is proven to be unsolvable in general, and is intractable using state-of-the-art theorem proving technology ... AFAIK.)
And I think that this road-block would apply to any approach where you could inject arbitrary Java code into the logic that is used to reflectively select a method from an object's class.
To my mind, the only moderately practical approach at the moment would be to replace the reflective code with something that generates and compiles Java source code. If this process occurs before you "run" the application, you've satisfied the requirement for static type-safety.
I was more asking about reflection in which the result is always the same. I.E. Person.class.getMethod("getPhoneNumber", null) would always return the same method and it's entirely possible to resolve it at compile time.
What happens if after compiling the class containing this code, you change Person to remove the getPhoneNumber method?
The only way you can be sure that you can resolve getPhoneNumber reflectively is if you can somehow prevent Person from being changed. But you can't do that in Java. Runtime binding of classes is a fundamental part of the language.
(For record, if you did that for a method that you called non-reflectively, you would get an IncompatibleClassChangeError of some kind when the two classes were loaded ...)
It has been pointed out that in Java 8 and later you could declare your validator something like this:
public Result validateField(Object data,
SomeFunctionalInterface function,
ValidationOptions options) { ... }
where SomeFunctionalInterface corresponds to the (loosely speaking) common signature of the methods you are validating.
Then you can call it with a method reference; e.g.
validateField(data, SomeClass::someMethod, options)
This is approach is statically type-safe. You will get a compilation error if SomeClass doesn't have someMethod or if it doesn't conform to SomeFunctionalInterface.
But you can't use a string to denote the method name. Looking up a method by name would entail either reflection ... or something else that side-steps static (i.e. compile time / load time) type safety.
Java misses the syntax sugar to do something as nice as Person.phoneNumber.getter. But if Person is an interface, you could record the getter method using a dynamic proxy. You could record methods on non-final classes as well using CGLib, the same way Mockito does it.
MethodSelector<Person> selector = new MethodSelector<Person>(Person.class);
selector.select().getPhoneNumber();
validateField(data, selector.getMethod(), options);
Code for MethodSelector: https://gist.github.com/stijnvanbael/5965609
Inspired by mocking frameworks, we could dream up the following syntax:
validator.validateField(data, options).getPhoneNumber();
Result validationResult = validator.getResult();
The trick is the generic declaration:
class Validator {
public <T> T validateField(T data, options) {...}
}
Now the return type of the method is the same as your data object's type and you can use code completion (and static checking) to access all the methods, including the getter methods.
As a downside, the code isn't quite intuitive to read, since the call to the getter doesn't actually get anything, but instead instructs the validator to validate the field.
Another possible option would be to annotate the fields in your data class:
class FooData {
#Validate(new ValidationOptions(...))
private PhoneNumber phoneNumber;
}
And then just call:
FooData data;
validator.validate(data);
to validate all fields according to the annotated options.
The framework picklock lets you do the following:
class Data {
private PhoneNumber phoneNumber;
}
interface OpenData {
PhoneNumber getPhoneNumber(); //is mapped to the field phoneNumber
}
Object data = new Data();
PhoneNumber number = ObjectAccess
.unlock(data)
.features(OpenData.class)
.getPhoneNumber();
This works in a similar way setters and private methods. Of course, this is only a wrapper for reflection, but the exception does not occur at unlocking time not at call time. If you need it at build time, you could write a unit test with:
assertThat(Data.class, providesFeaturesOf(OpenData.class));
I found a way to get the Method instance using Lambdas. It works only on interface methods though currently.
It works using net.jodah:typetools which is a very lightweight library.
https://github.com/jhalterman/typetools
public final class MethodResolver {
private interface Invocable<I> {
void invokeWithParams(I instance, Class<?>[] parameterTypes) throws Throwable;
}
interface ZeroParameters<I, R> extends Invocable<I> {
R invoke(I instance) throws Throwable;
#Override
default void invokeWithParams(I instance, Class<?>[] parameterTypes) throws Throwable {
invoke(instance);
}
}
public static <I, R> Method toMethod0(ZeroParameters<I, R> call) {
return toMethod(ZeroParameters.class, call, 1);
}
interface OneParameters<I, P1, R> extends Invocable<I> {
R invoke(I instance, P1 p1) throws Throwable;
#Override
default void invokeWithParams(I instance, Class<?>[] parameterTypes) throws Throwable {
invoke(instance, param(parameterTypes[1]));
}
}
public static <I, P1, R> Method toMethod1(OneParameters<I, P1, R> call) {
return toMethod(OneParameters.class, call, 2);
}
interface TwoParameters<I, P1, P2, R> extends Invocable<I> {
R invoke(I instance, P1 p1, P2 p2) throws Throwable;
#Override
default void invokeWithParams(I instance, Class<?>[] parameterTypes) throws Throwable {
invoke(instance, param(parameterTypes[1]), param(parameterTypes[2]));
}
}
public static <I, P1, P2, R> Method toMethod2(TwoParameters<I, P1, P2, R> call) {
return toMethod(TwoParameters.class, call, 3);
}
private static final Map<Class<?>, Object> parameterMap = new HashMap<>();
static {
parameterMap.put(Boolean.class, false);
parameterMap.put(Byte.class, (byte) 0);
parameterMap.put(Short.class, (short) 0);
parameterMap.put(Integer.class, 0);
parameterMap.put(Long.class, (long) 0);
parameterMap.put(Float.class, (float) 0);
parameterMap.put(Double.class, (double) 0);
}
#SuppressWarnings("unchecked")
private static <T> T param(Class<?> type) {
return (T) parameterMap.get(type);
}
private static <I> Method toMethod(Class<?> callType, Invocable<I> call, int responseTypeIndex) {
Class<?>[] typeData = TypeResolver.resolveRawArguments(callType, call.getClass());
Class<?> instanceClass = typeData[0];
Class<?> responseType = responseTypeIndex != -1 ? typeData[responseTypeIndex] : Void.class;
AtomicReference<Method> ref = new AtomicReference<>();
I instance = createProxy(instanceClass, responseType, ref);
try {
call.invokeWithParams(instance, typeData);
} catch (final Throwable e) {
throw new IllegalStateException("Failed to call no-op proxy", e);
}
return ref.get();
}
#SuppressWarnings("unchecked")
private static <I> I createProxy(Class<?> instanceClass, Class<?> responseType,
AtomicReference<Method> ref) {
return (I) Proxy.newProxyInstance(MethodResolver.class.getClassLoader(),
new Class[] {instanceClass},
(proxy, method, args) -> {
ref.set(method);
return parameterMap.get(responseType);
});
}
}
Usage:
Method method = MethodResolver.toMethod2(SomeIFace::foobar);
System.out.println(method); // public abstract example.Result example.SomeIFace.foobar(java.lang.String,boolean)
Method get = MethodResolver.<Supplier, Object>toMethod0(Supplier::get);
System.out.println(get); // public abstract java.lang.Object java.util.function.Supplier.get()
Method accept = MethodResolver.<IntFunction, Integer, Object>toMethod1(IntFunction::apply);
System.out.println(accept); // public abstract java.lang.Object java.util.function.IntFunction.apply(int)
Method apply = MethodResolver.<BiFunction, Object, Object, Object>toMethod2(BiFunction::apply);
System.out.println(apply); // public abstract java.lang.Object java.util.function.BiFunction.apply(java.lang.Object,java.lang.Object)
Unfortunately you have to create a new interface and method based on the parameter count and whether the method returns void or not.
However, if you have a somewhat fixed/limited method signature/parameter types, then this becomes quite handy.

Categories