I'm learning android studio 4.1 using Kotlin from a 2020 book. In one of the examples they are using a MutableLiveData object. When I try to use code completion with this line:
result.setValue(value.toFloat()*usd_to_eu_rate)
the only option is the setter result.value tough result.setValue does work just fine. So I was wondering what the difference is between the two and why value does not show up in code compleation.
Thanks to this link - kotlinlang.org/docs/reference/java-interop.html#getters-and-setters - provided by #IR42 and other information by other contributors whos comments were unfortunately deleted I found my answer:
MutableLiveData is a Java class and Kotlin will infer a property when the Java class has methods that follow the Java conventions for getters and setters (no-argument methods with names starting with get and single-argument methods with names starting with set)
Code completion will not suggest the Java getter methods (i.e. getValue and setValue) but it will suggest the Kotlin inferred property (i.e. value)
You can still use the Java getter/setter methods but this is discouraged.
Related
I'm in the process of trying to migrate a R# extension project from R# 6 to R# 8. (I've taken over a project that someone wrote, and I'm new to writing extensions.)
In the existing v6 project there is a class that derives from RenameWorkflow, and the constructor used to look like this;
public class RenameStepWorkflow : RenameWorkflow
{
public RenameStepWorkflow(ISolution Solution, string ActionId)
: base(Solution, ActionId)
{
}
This used to work in R# SDK v 6, but now in V8, RenameWorkflow no longer has a constructor that takes Solution and actionId. The new constructor signature now looks like this;
public RenameWorkflow(
IShellLocks locks,
SearchDomainFactory searchDomainFactory,
RenameRefactoringService renameRefactoringService,
ISolution solution,
string actionId);
now heres my problem that I need help with (I think)
I've copied the constructor, and now the constructor of this class has to satisfy these new dependancies. Through some digging I've managed to find a way to satisfy all the dependencies, except for 'SearchDomainFactory'. The closest I can come to instantiating via the updated constructor is as follows;
new RenameStepWorkflow(Solution.Locks, JetBrains.ReSharper.Psi.Search.SearchDomainFactory.Instance, RenameRefactoringService.Instance, this.Solution, null)
All looks good, except that JetBrains.ReSharper.Psi.Search.SearchDomainFactory.Instance is marked as Obsolete, and gives me a compile error that I cannot work around, even using #pragma does not allow me to compile the code. The exact error message I get when I compile is Error 16 'JetBrains.ReSharper.Psi.Search.SearchDomainFactory.Instance' is obsolete: 'Inject me!'
Obvious next question..ok, how? How do I 'inject you'? I cannot find any documentation over this new breaking change, in fact, I cannot find any documentation (or sample projects) that even mentions DrivenRefactoringWorkflow or RenameWorkflow, (the classes that now require the new SearchDomainFactory), or any information on SearchDomainFactory.Instance suddenly now obsolete and how to satisfy the need to 'inject' it.
Any help would be most appreciated! Thank you,
regards
Alan
ReSharper has its own IoC container, which is responsible for creating instances of classes, and "injecting" dependencies as constructor parameters. Classes marked with attributes such as [ShellComponent] or [SolutionComponent] are handled by the container, created when the application starts or a solution is loaded, respectively.
Dependencies should be injected as constructor parameters, rather than using methods like GetComponent<TDependency> or static Instance properties, as this allows the container to control dependency lifetime, and ensure you're depending on appropriate components, and not creating leaks - a shell component cannot depend on a solution component for instance, it won't exist when the shell component is being created.
ReSharper introduced the IoC container a few releases ago, and a large proportion of the codebase has been updated to use it correctly, but there are a few hold-outs, where things are still done in a less than ideal manner - static Instance properties and calls to GetComponent. This is what you've encountered. You should be able to get an instance of SearchDomainFactory by putting it as a constructor parameter in your component.
You can find out more about the Component Model (the IoC container and related functionality) in the devguide: https://www.jetbrains.com/resharper/devguide/Platform/ComponentModel.html
I'm generating a jaxws client based on webservice. Jaxb will generate booleans using the java.lang.Boolean instead of the primitive type. In addition to this, it will generate the is() naming convention for beans.
However if I try to link the boolean (e.g. isOptional()) to a checkbox, it will throw the following exception:
value="#{property.optional}": Property 'optional' not readable on type java.lang.Boolean
My google skills have informed me that jsf works fine with:
boolean isOptional()
boolean getOptional()
Boolean getOptional()
But not with
Boolean isOptional()
However it is not feasible to update the beans manually due to the size and amount of the webservices, so is there any way to make jsf use the java.lang.Boolean isOptional() properly? Or can I somehow define a property in the jaxb bindings file at generation time which magically generates "getOptional()"?
On a sidenote, the following does work:
<h:selectBooleanCheckbox value="#{property.isOptional()}"/>
However I can't actually update the value presumably because it can't find the setter.
EDIT: I'm running the latest jdk 7, the output of "java -version":
java version "1.7.0_05"
Java(TM) SE Runtime Environment (build 1.7.0_05-b05)
Java HotSpot(TM) Client VM (build 23.1-b03, mixed mode, sharing)
The output of "wsimport -version":
JAX-WS RI 2.2.4-b01
Generated code:
public Boolean isOptional() {
return optional;
}
Jaxb will generate booleans using the java.lang.Boolean instead of the primitive type. In addition to this, it will generate the is() naming convention for beans.
Using the is getter prefix for java.lang.Boolean was a known major mistake of JAXB. It has been fixed in version 2.1.13 which was released April 2010 already. Keep your libraries up to date.
See also this blog article for some background.
The Great JAXB API Blunder
September 15, 2006
You've got to hand it to Sun for screwing this one up. It's one thing to write software that doesn't adhere to a specification when the documentation is as thick as a textbook. Take, for example, just about anything created by the W3C. However, it's really bad when it is your own spec that you can't follow, especially when it is the most well known part of it. That's right, Sun missed by a mile on their own spec when they created the JAXB 2.0 API. The JAXB 2.0 compiler (XJC) incorrectly uses the prefix "is" rather than "get" when generating the getter method for a java.lang.Boolean property. While the JavaBean spec states that read methods for primitive booleans can use the alternate "is" prefix, this flexibility does not extend to its boolean wrapper counterpart.
8.3.2 Boolean Properties
In addition, for boolean properties, we allow a getter method to match the pattern:
public boolean is();
This "is" method may be provided instead of a "get" method, or it may be provided in addition to a "get" method. In either case, if the "is" method is present for a boolean property then we will use the "is" method to read the property value.
An example boolean property might be:
public boolean isMarsupial();
public void setMarsupial(boolean m);
Given that JAXB is a code generation framework, and the idea behind code generation frameworks is that the code is to be used "as is" and not modified thereafter, this is a pretty big "oops". While this issue has been reported, the response from Sun is "sorry, its too late".
This behavior is governed by the spec, and unfortunately it's just too late for the spec to change now.
In terms of the user experience, thanks to auto-boxing, I don't think this will be a real issue for people. Is the problem that you are using Introspector and it's missing the property?
Too late? Not a real issue? It's BROKEN. FIX IT! I also don't like the naive statement that it probably won't affect frameworks. Um, yes it will, considering other projects did happen to adhere to the spec (hibernate, spring, myfaces, etc.)
UPDATE: Stevo Slavic informed me that this has been fixed in JAXB 2.1.13. See JAXB-131 for details. Yeah!
JSF/EL is not at fault here. It's doing its job properly conform the JavaBeans spec.
I'm not sure why the latest and greatest JAXB version still generates the wrong method but I finally fixed it by adding "-B-enableIntrospection" (as per http://jaxb.java.net/2.2.4/docs/xjc.html) to the wsimport call. This results in:
public Boolean getOptional() {
return optional;
}
Is it possible in J2ME to call/invoke a method by its name.just like we have getDeclaredMethod in java .
The java.lang.reflect package is available only in CDC 1.1.2. If you're not on such configuration, you're out of luck. There is no way to invoke a method by name without reflection.
A workaround would be to create a map from strings (method names) to appropriate classes on which you can invoke the methods.
Closest you can get is to instantiate a class by name using Class.forName("com.class.ClassName").newInstance() -- that will execute a parameterless constructor.
From within IntelliJ IDEA, when I'm within a groovy class, and refer to a property / field on java class that doesn't exist, is there a way to enable the create property refactoring?
Eg:
// Inside Foo.groovy
void method()
{
Bar bar = new Bar(); // Defined in Bar.java
bar.someProperty = "Hello, world"; // bar.someProperty doesn't exist.
}
In the above example, I'd like to get access to the "create property" refactoring option on someProperty. Is there a way to enable this?
Note: I'm using IntelliJ 10.
As of now, refactorings for Groovy in IntelliJ are pretty limited compared to Java. The reason for this is Groovy is an optionally typed language, so the IDE needs much more 'brain' for Groovy refactorings than for Java.
create property currently does not exist for Groovy.
IMHO the only thing you can do is filing a ticket on http://youtrack.jetbrains.net. Jetbrains is very responsive - I know from own experience.
I have an Expando class which I need to inspect its properties from Java.
In Groovy:
def worker = new Expando()
worker.name = "John"
worker.surname = "Doe"
In Java:
Introspector.getBeanInfo(groovyObject.getClass())
Is it possible to compile at runtime the class from the object in Groovy?
The Expando is completely dynamic. It does not generate any bytecode getters or setters and therefore cannot be used as a JavaBean. What do you need to use the bean introspector for? You may be able to implement that logic using the expando directly if you write it in Groovy.
You might try the JSR 223 / Script engine with Groovy (example here) if you are using Java 6. It allows you to evaluate Groovy code from Java.
Depending on the location/definition of the Expando, you might be able to get its properties by evaluating getProperties() (as of Groovy 1.7).