I have created an interface on kotlin.
interface IDataManager{
val dataType: String?
}
Now I am trying to get its variable in my java class, like following.
public static DataWrapper getInstance(IDataManager iDataManager) {
dataType= iDataManager.dataType;
return instance;
}
But I am getting error: cannot find symbol iDataManager.dataType
Please call getter function to get a value of the variable:
dataType = iDataManager.getDataType();
If we use properties on Kotlin side we should use getters and setters to access those properties on Java side.
edit - as Alexey points out in the comments, this doesn't work for interfaces, since the property needs a backing field and properties in interfaces can't have those. It's still useful to know, but it doesn't apply to the OP's question
As well as what Sergey said, you can add the #JvmField annotation on things if you want to expose them as a field instead of generating the getters and setters
interface IDataManager{
#JvmField val dataType: String?
}
#JvmStatic is another useful one for Java interop, you can put it on properties and functions in companion objects, so instead of this
Utils.Companion.coolUtility()
you can do this (like you're used to)
Utils.coolUtility()
Related
I have the following declaration:
val selectedPhotos: MutableLiveData<List<Photo>> = MutableLiveData()
I have the following method that should return the selectedPhotos which is a MutableLiveData type.
fun getSelectedPhotos(): MutableLiveData<List<Photo>> {
return selectedPhotos
}
However, the following give me an error:
Platform declaration clash: The following declarations have the same JVM signature (getSelectedPhotos()Landroidx/lifecycle/MutableLiveData;):
fun <get-selectedPhotos>(): MutableLiveData<List<Photo>> defined in com.raywenderlich.android.combinestagram.SharedViewModel
fun getSelectedPhotos(): MutableLiveData<List<Photo>> defined in com.raywenderlich.android.combinestagram.SharedViewModel
However, If I change the fun to return the following everything works ok:
fun getSelectedPhotos(): LiveData<List<Photo>> {
return selectedPhotos
}
However, looking at the following MutableLiveData extends LiveData
public class MutableLiveData<T> extends LiveData<T> {
...
}
Just confused about why I can't use MutableLiveData as the return type which is the correct type that I have declared.
Many thanks in advance,
When you declare something in kotlin, the kotlin creates it's setter and getter for you. So considering you declare var abc, kotlin will declare setAbc and getAbc, which is very handful for data classes.
In your case since your property name is selectedPhotos, kotlin would have already created a getter with name getSelectedPhotos with return type MutableLiveData>. Due to this, you are getting clash as two methods have same name and return type.
In your case, you don't need to declare this getSelectedPhotos explicitly, as the kotlin has already declared that for you. You can access that getter and setter declared by kotlin in both kotlin and JAVA class.
Edit:
In case, you want to look into the generated JAVA class for your kotlin file, open your kotlin file and then go to Tools -> Kotlin -> Show Kotlin Bytecode and then click on Decomplie button present on opened screen.
C# 6.0 introduced the nameof() operator, that returns a string representing the name of any class / function / method / local-variable / property identifier put inside it.
If I have a class like this:
class MyClass
{
public SomeOtherClass MyProperty { get; set; }
public void MyMethod()
{
var aLocalVariable = 12;
}
}
I can use the operator like this:
// with class name:
var s = nameof(MyClass); // s == "MyClass"
// with properties:
var s = nameof(MyClass.OneProperty); // s == "OneProperty"
// with methods:
var s = nameof(MyClass.MyMethod); // s == "MyMethod"
// with local variables:
var s = nameof(aLocalVariable); // s == "aLocalVariable".
This is useful since the correct string is checked at compile time. If I misspell the name of some property/method/variable, the compiler returns an error. Also, if I refactor, all the strings are automatically updated. See for example this documentation for real use cases.
Is there any equivalent of that operator in Java? Otherwise, how can I achieve the same result (or similar)?
It can be done using runtime byte code instrumentation, for instance using Byte Buddy library.
See this library: https://github.com/strangeway-org/nameof
The approach is described here: http://in.relation.to/2016/04/14/emulating-property-literals-with-java-8-method-references/
Usage example:
public class NameOfTest {
#Test
public void direct() {
assertEquals("name", $$(Person.class, Person::getName));
}
#Test
public void properties() {
assertEquals("summary", Person.$(Person::getSummary));
}
}
Sadly, there is nothing like this. I had been looking for this functionality a while back and the answer seemed to be that generally speaking, this stuff does not exist.
See Get name of a field
You could, of course, annotate your field with a "Named" annotation to essentially accomplish this goal for your own classes. There's a large variety of frameworks that depend upon similar concepts, actually. Even so, this isn't automatic.
You can't.
You can get a Method or Field using reflection, but you'd have to hardcode the method name as a String, which eliminates the whole purpose.
The concept of properties is not built into java like it is in C#. Getters and setters are just regular methods. You cannot even reference a method as easily as you do in your question. You could try around with reflection to get a handle to a getter method and then cut off the get to get the name of the "property" it resembles, but that's ugly and not the same.
As for local variables, it's not possible at all.
You can't.
If you compile with debug symbols then the .class file will contain a table of variable names (which is how debuggers map variables back to your source code), but there's no guarantee this will be there and it's not exposed in the runtime.
I was also annoyed that there is nothing comparable in Java, so I implemented it myself: https://github.com/mobiuscode-de/nameof
You can simply use it like this:
Name.of(MyClass.class, MyClass::getProperty)
which would just return the String
"property"
It's also on , so you can add it to your project like this:
<dependency>
<groupId>de.mobiuscode.nameof</groupId>
<artifactId>nameof</artifactId>
<version>1.0</version>
</dependency>
or for Gradle:
implementation 'de.mobiuscode.nameof:nameof:1.0'
I realize that it is quite similar to the library from strangeway, but I thought it might be better not to introduce the strange $/$$ notation and enhanced byte code engineering. My library just uses a proxy class on which the getter is called on to determine the name of the passed method. This allows to simply extract the property name.
I also created a blog post about the library with more details.
Lombok has an experimental feature #FieldNameConstants
After adding annotation you get inner type Fields with field names.
#FieldNameConstants
class MyClass {
String myProperty;
}
...
String s = MyClass.Fields.myProperty; // s == "myProperty"
I am using a Kotlin class from Java code. My Kotlin class looks like:
class Something {
var a = 0
}
I want to be able to access a from Java code like
s = new Something();
s.a = 5;
however, I only have s.getA() and s.setA(5). Is there any way to make this property directly settable and gettable from Java? Obviously we can't have custom getter and setter in this case.
You can annotate a property with the #JvmField annotation to expose it as a Java field.
If you need to expose a Kotlin property as a field in Java, you need to annotate it with the #JvmField annotation. The field will have the same visibility as the underlying property. You can annotate a property with #JvmField if it has a backing field, is not private, does not have open, override or const modifiers, and is not a delegated property.
I want to load a resource in a top level function using Class.getResourceAsStream().
Is there any way to get a reference to the class that the top level function will be compiled into so that I can write, for example
val myThing = readFromStream(MYCLASS.getResourceAsStream(...))
Another way I found is to declare a local class or an anonymous object inside a top level function and to get its enclosingClass:
val topLevelClass = object{}.javaClass.enclosingClass
Note: to work, this declaration should be placed on top level or inside a top-level function.
Then you can use the topLevelClass as a Class<out Any>:
fun main(args: Array<String>) {
println(topLevelClass) // class MyFileNameKt
}
With Java 7 you can get a reference to the current Java class from a top level function using
MethodHandles.lookup().lookupClass()
No, there is no syntax to reference that class. You can access it using Class.forName(). For example, if the file is called "Hello.kt" and is located in the package "demo", you can obtain the class by calling Class.forName("demo.HelloKt").
In the absence of a way to get a reference directly, I've fallen back on creating an anonymous object in the current package
val myThing = object: Any() {}.javaClass.getResourceAsStream(...)
As linters like detekt would flag anonymous classes as EmptyClassBlock you could also use something like
internal object Resources
fun resourceStream(name: String): InputStream {
return Resources.javaClass.getResourceAsStream(name)
}
IS it possible to use the java reflection api in GWT client side? I want to use reflections to find the value of a property on a Javabean. Is this possible?
You can use the GWT Generators functionality that allows you to generate code during the GWT compile phase.
Your bean, that you want to introspect, can extend a class that has a method defined as
public Object getProperty(String propertyName){}
Let's call this class IntrospectionBean.
Let's say that you then have your bean defined as:
public class MyBean extends IntrospectionBean {
private String prop1;
private String prop2;
}
The GWT generator will have access to all fields of MyBean and it can generate the getProperty(String propertyName) method during GWT compile time, after iterating through all fields of MyBean.
The generated class might look like this:
public class MyBean extends IntrospectionBean {
private String prop1;
private String prop2;
public Object getProperty(String propertyName) {
if ("propr1".equals(propertyName)) {
return prop1;
}
if ("propr2".equals(propertyName)) {
return prop2;
}
return null;
}
}
You could simply then use myBean.getProperty("prop1") in order to retrieve a property based on it's name at runtime.
Here you can find an example of how to implement a gwt generator
I've been there and the solution indeed is to use Deferred Binding and Generators. You can see a use of Generators to overcome the lack of Reflection in GWT client here:
http://jpereira.eu/2011/01/30/wheres-my-java-reflection/
Hope it helps.
Since GWT code is translated to Javascript direct usage of reflection API is not supported.
There is a small project GWT-Reflection, that allows to use reflection in GWT.
I have made my gwt-reflection library public.
https://github.com/WeTheInternet/xapi/tree/master/gwt/gwt-reflect
https://github.com/WeTheInternet/gwt-sandbox/tree/xapi-gwt/user/src/com/google/gwt/reflect
Due to classpath issues with trying to make Gwt pick my version of Class.java over its own, I finally just forked Gwt, added java 8 and reflection support, and now maintain net.wetheinter:gwt-*:2.7.0 which has this support baked in (I will release a 2.8 some time after Gwt 2.8 goes live)
It supports three levels of reflection:
Monolithic:
// Embeds all data needed to perform reflection into hidden fields of class
GwtReflect.magicClass(SomeClass.class);
SomeClass.getField(fieldName).set(null, 1);
Lightweight:
// Allows direct reflection, provided ALL parameters are literals, or traced to literals
SomeClass.class.getField("FIELD_NAME").set(null, 1);
Flyweight:
// Skips creating a Field object entirely, and just invokes the accessor you want
// All params must be literals here as well
GwtReflect.set(SomeClass.class, "FIELD_NAME", null, 1);
These examples also work for Methods and Constructors. There's basic support for annotations, and more to come in the future.
GWT not support reflection fully, you can see bellow link :
http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsCompatibility.html
You should note the border between java and javascript. In GWT, all code compiles to javascript, so you have to check if JavaScript is a well-defined reflection.
If you just want to use reflection to grab a private field, consider using jsni (javascript native interface) instead; it has no notion of private or public, so you can just grab anything you want like so:
package com.foo;
class SomeClass {
private String someField;
private static int someInt;
}
//accessors:
native String ripField(SomeClass from)
/*-{
return from.#com.foo.SomeClass::someField;
}-*/;
native int ripInt()
/*-{
return #com.foo.SomeClass::someInt;
}-*/;
Also, I am in the middle of finishing up emulation for java.lang.Class newInstance / reflection.
I'll post back here with a link in about two days if you'd like to play with it.
It requires that you pass a class through a method which I route to a custom generator
(like GWT.create, except it returns a generated java.lang.Class with field and method accessors that just point to jsni methods / fields. :)