I am re writing a library originally written in C# into Java and am trying my best to follow it as closely as possible. This, however, has me stumped.
This is the C# method I want to recreate in Java
public T With<TV>(Func<T, IEditable> func, TV value)
{
var pageElement = func(TypedThis);
pageActions.Add(new WebDriverValuePageAction<TV>(pageElement, value));
return TypedThis;
}
This is a generic method which is used as part of a Selenium Page Object framework where T is a BasePage and the Method takes any page element inheriting the IEditable interface.
What is stumping me is the With<TV> part of the method and how to recreate this in Java. Everything else is pretty much done. I have been able to recreate T but cannot work out how to also pass in TV (essentially a generic value) along with the function.
Direct equivalent will be
public <TV> T With(Function<T, IEditable> func, TV value)
{
IEditable pageElement = func.apply(TypedThis);
pageActions.Add(new WebDriverValuePageAction<TV>(pageElement, value));
return TypedThis;
}
Related
I have a Kotlin library that I'm attempting to call from Java. I haven't worked with Kotlin before.
The Kotlin library function is as follows:
suspend fun decode(jwt: String): UsefulThing {
// does a bunch of stuff, removed for brevity.
return otherthing.getUsefulThing(jwt)
}
How can I call this from Java? So far I've tried:
Continuation<UsefulThing> continuation = new Continuation<>() {
#NotNull
#Override
public CoroutineContext getContext() {
return EmptyCoroutineContext.INSTANCE;
}
#Override
public void resumeWith(#NotNull Object o) {
System.out.println("Result of decode is " + o);
}
};
// Call decode with the parameter and continuation.
Object result = UsefulThingKt.decode(JWT, continuation);
// result is COROUTINE_SUSPENDED
I never see any console output. Looks like the continuation is never called, or it's run in another context. I've pored over other answers and coroutines seem to have gone through a number of iterations - I can't find an explanation that really makes sense to me.
I should note that I'm running on Java 11.
How can I simply call the kotlin function?
I suggest to not even try. Suspend functions were never meant for Java interop.
Instead, convert it on the Kotlin side to something that Java understands - to CompletableFuture:
fun decodeAsync(jwt: String): CompletableFuture<UsefulThing> = GlobalScope.future { decode(jwt) }
We can freely mix Java and Kotlin code in a single module, so you can create such wrapper inside your project.
Depending on your case you could use GlobalScope (in Java we don't have structured concurrency) or you could create a custom CoroutineScope and handle its lifecycle manually.
I am struggling trying to convert a 'method call' to the 'method object' of that method.
I have:
someClassInstance.someInstanceMethod(new Function<Person, Method>() {
#Override
public Method apply(Person p) {
return p.getAge(); // I want to convert 'p.getAge()' to the the method of 'getAge'
}
});
I know I can simplify this with lambda's but I thought this would make what I want to do more clear.
p.getAge()
currently returns an 'int', but I want it to return the 'Method object' of 'getAge()'.
What I Mean by the 'Method object' is this:
Method method = Person.class.getMethod("getAge"); // I basically want to return this.
The reason for this is, I'm building my own little framework to gain experience and letting the user use:
someClassInstance.someInstanceObject((Function<Person, Method>) o -> o.getAge());
Seems more user friendly.
NOTE: I do have my own interface of 'Function' that does not take 'Method' as a second generic type so the user only has to type:
someClassInstance.<Person>someInstanceMethod(o -> o.getAge());
After searching for some more days I finally found an answer, somewhere in the comments of an old stack overflow question, I found this link:
https://stackoverflow.com/a/22745127/3478229
This answer from another question links to a library written by 'Benji Weber' this library used 'cglib' to create proxy objects to get the method of a Function<T, U>.
Meaning:
someMethod(Person::getAge) //returns a String 'age'.
I am using this library which is a CalendarView. https://github.com/kizitonwose/CalendarView
In the sample code there is the following code which attaches a Scroll Listener to the CalendarView
calendarView.monthScrollListener = { // etc}
I am unsure how to translate this to Java, I try the following but the "MonthScrollListener" class is nowhere to be found, its like it want some other type but I cannot find the type. Everything else has worked so far when translating the Kotlin to Java but I cannot see how this might work
mBinding.calendarView.setMonthScrollListener(new MonthScrollListener(){ // etc});
What should I pass into the setMonthScrollListener() method?
Edit: when I "ctrl click" on the setMonthScrollListener() it takes me into the CalendarView class and there is the following line:
public final var monthScrollListener: com.kizitonwose.calendarview.ui.MonthScrollListener? /* = ((com.kizitonwose.calendarview.model.CalendarMonth) -> kotlin.Unit)? */ /* compiled code */
So I try explicitly referencing the MonthScrollListener but everything is resolved up to the MonthScrollListener, which isnt available...
typealias is not visible in Java, but given the example you're talking about is:
typealias MonthScrollListener = (CalendarMonth) -> Unit
Then in Java world it should be similar to single method interface like (more about it below):
import kotlin.Unit;
interface MonthScrollListener {
Unit whatever(CalendarMonth cm);
}
It could be void because this is what Unit means in Kotlin but you know - life.
So passing Lambda in that method which expects listener should look like:
whatever.setMonthScrollListener((CalendarMonth cm) -> {
// w00t
return kotlin.Unit.INSTANCE;
});
I've basically ended up writing the same approach as suggested by #MishaAkopov
Edit (after reading about it):
But what type is it actually? It appears that Kotlin standard library has a bunch of interfaces like Function0<R> and Function2<P1,P2,R> that have one method invoke. So if you'd need to use above Kotlin code in previous Java versions it would instead look like:
Function1<CalendarMonth, Unit> listener = new Function1<CalendarMonth, Unit>() {
#Override
public Unit invoke(CalendarMonth cm) {
// Do something with calendar month
return kotlin.Unit.INSTANCE;
}
}
whatever.setMonthScrollListener(listener);
I have to develop an "generic" wigdet for a GWT/GXT project and to do so I need to create an instance of an object which type is unknown. I found an approach that works perfectly in dev mode but as soon as I try to compile my project and deploy it I get an Only class literals may be used as arguments to GWT.create() error.
Here is a sample of what I do:
public class GenericEditableGrid<M> extends Grid<M>{
private final ToolBar toolBar = new ToolBar();
private final TextButton newItemButton = new TextButton();
protected GridInlineEditing<M> editing;
private final Class<M> clazzM;
public GenericEditableGrid(Class<M> parametrizedClass, String gridTitle, ListStore<M> listStore, ColumnModel<M> cm) {
super(listStore, cm);
clazzM = parametrizedClass;
// ... then I create my widget
bind();
}
private void bind(){
newItemButton.addSelectHandler(new SelectEvent.SelectHandler() {
#Override
public void onSelect(SelectEvent selectEvent) {
editing.cancelEditing();
// it is the folliwing line which is the problem obviously
M element = GWT.create(clazzM);
getStore().add(0, element);
int index = 0;
editing.startEditing(new Grid.GridCell(getStore().indexOf(element), index));
}
});
}
}
And this is how I use it in my subclasses:
super(InternationalString.class, gridTitle, new ListStore<InternationalString>(isprops.key()), buildColumnModel());
Basically, I would like to know what the problem is exactly with this approach and eventually how I should do to make it well.
Please note that my concern is not just to make it work, but more to do it the right way. As I could just avoid the problem using an abstract method which would handle the GWT.create() method in the daughter classes. But this is not the design I want, it just doesn't look right.
What I don't get also is what's the difference between doing this:
MyClass e = GWT.create(MyClass.class);
and:
Class<MyClass> clazz=MyClass.class;
MyClass e = GWT.create(clazz);
Because as far as I am concerned I think this is basically what I am doing and it looks like the same thing. Isn't it?
There's a well-worded explanation in this forum:
As the error message indicates, only class literals may be passed to the GWT.create method. The reason for this is that all GWT.create calls are basically turned into constructors at compile time, using the deferred binding rules for your module. As a result, all classes must be decided at compile time - your code requires that the at runtime the class is decided. This is too late, and so cannot be compiled.
GWT is not proper java, and so cannot be always treated as java. This is one such example of things that cannot be done in gwt. ...
What is it you are trying to do? Either you are making it far more complicated than it needs to be, or you need to write a generator to do it instead of taking this approach.
I'm fairly new to Java. I'm coming from PHP and I used to create registry classes in php using the magic __get and __set methods. So that other parts of the system can easily do:
registry.foo = new Foo();
I should mention I'm trying to create game engine. Here is my registry in Java atm:
class Registry {
private static Map<String, Object> box = new HashMap<String, Object>();
public static Object get(String key) {
if (Registry.box.get(key) != null) {
return Registry.box.get(key);
}else {
return null;
}
}
public static void set(String key, Object o) {
Registry.box.put(key, o);
}
}
Then for the other parts of the system to access the registry, I currently need this whole thing:
((Object) Registry.get("Object")).doSomething();
Which is really a lot of code. In php this would be accomplished by simply:
Registry.foo.doSomething();
Any way to make this a bit more simpler? I guess I could make public fields, but then the regsitry class would need to implicitly create these fields as the possibility of new objects may need to be added which are unknown to the registry class itself, which is.. annoying :P
Thanks in advance!
This is a two pronged problem:
Java is a statically type language, and does not offer in-language flexibility for defining objects at runtime (you can use a library to synthesize classes at runtime, but, see #2)
A global registry for objects defeats a lot of safeties in a type-safe language. If your entire application centers around getting and putting objects into a global Map, there likely safer and less-coupled designs.
How can this be solved?
Redesign your application structure to not need a global map.
Use a dynamic language subset for Java (such as Groovy).
Use Scala 2.10 (JVM compatible) which features a Dynamic type which does exactly what you want.
First of all this method is too verbose:
public static Object get(String key) {
if (Registry.box.get(key) != null) {
return Registry.box.get(key);
}else {
return null;
}
}
It could be just:
public static Object get(String key) {
return Registry.box.get(key);
}
But second, this is definitely a bad design. Global repository - doesn't sound reasonable. A storage of objects of all types by string key - it's terrible.
Any way to make this a bit more simpler?
Not in any practical way. Java is a statically typed language, and the structure of objects has to be known up front. The very idea of an equivalent of PHP's __get and __set is antithetical to the language.
For what it's worth, your "registry" looks like bad design anyway. (Admittedly making some pretty wild assumptions from the little code you've shown.) You shouldn't need a global repository of what appear to be unrelated objects. You should consider some sort of dependency injection instead.
Based on your comment, instead of structuring your code like this:
class World implements GameSystem {
public void update() {
Registry.get("game").doSomething();
}
}
you should do:
class World implements GameSystem {
Game game;
public World(Game game) { // and other dependencies
this.game = game;
}
public void update() {
this.game.doSomething();
}
}
The idea is that components of your program don't really have any business knowing how to find the other components. It also makes dependencies between the components explicit, and helps you avoid circular dependencies.