Kotlin access Java field directly instead of using getter/setter - java

For example, here is a Java class
public class Thing {
...
public int thing;
public int getThing() { return thing; }
public void setThing(int t) { thing = t; }
}
In Kotlin, if I want to access thing, I would do the following:
val t = Thing()
t.thing // get
t.thing = 42 //set
In the decompiled Kotlin bytecode, what I see is Kotlin using getter and setter:
t.getThing()
t.setThing(42)
I wonder if there is a way to directly access the field t.thing instead of using getter and setter?

I'm not sure the byte code you're looking at is giving you you the full explanation.
I modified your test class to give getThing() and setThing() different behaviour to the underlying field:
public class Thing {
public int thing;
public int getThing() { return thing + 1; }
public void setThing(int t) { thing = 0; }
}
Then when running this Kotlin code:
fun main() {
val t = Thing()
t.thing = 1
println(t.thing)
println(t.getThing())
t.setThing(1)
println(t.thing)
println(t.getThing())
}
I get:
1
2
0
1
Which indicates that t.thing is in fact getting and setting the field directly.

You can access Java fields directly from the Kotlin code. So, if you don't have a getter, you can still access t.thing.
But I don't think it's possible to access the field when you have a getter. If you cannot edit the Java code but still want to access the field directly (to avoid side-effects in a getter or something), you can do it using another Java class. This way you can manage access to the field.
public class AnotherThing {
...
public Thing thing;
public getField() { return thing.thing; }
}

Related

Kotlin: How can I use delegated properties in Java?

I know that you can't use the delegated property syntax in Java, and won't get the convenience of "overriding" the set/get operators as in Kotlin, but I'd still like to use an existing property delegate in Java.
For instance, a simple delegate of an int:
class IntDelegate {
operator fun getValue(thisRef: Any?, property: KProperty<*>) = 0
}
In Kotlin of course we can use this like so:
val x by IntDelegate()
But how can we use IntDelegate in some form in Java? This is the start, I believe:
final IntDelegate x = new IntDelegate();
And then using the functions directly. But how can I use the getValue function? What do I pass for its parameters? How do I get a KProperty for Java field?
If you really want to know how Kotlin delegated property looks under the hood in Java, here it is: in this example a property x of a java class JavaClass is delegated to the Delegates.notNull standard delegate.
// delegation implementation details
import kotlin.jvm.JvmClassMappingKt;
import kotlin.jvm.internal.MutablePropertyReference1Impl;
import kotlin.jvm.internal.Reflection;
import kotlin.reflect.KProperty1;
// notNull property delegate from stdlib
import kotlin.properties.Delegates;
import kotlin.properties.ReadWriteProperty;
class JavaClass {
private final ReadWriteProperty<Object, String> x_delegate = Delegates.INSTANCE.notNull();
private final static KProperty1 x_property = Reflection.mutableProperty1(
new MutablePropertyReference1Impl(
JvmClassMappingKt.getKotlinClass(JavaClass.class), "x", "<no_signature>"));
public String getX() {
return x_delegate.getValue(this, x_property);
}
public void setX(String value) {
x_delegate.setValue(this, x_property, value);
}
}
class Usage {
public static void main(String[] args) {
JavaClass instance = new JavaClass();
instance.setX("new value");
System.out.println(instance.getX());
}
}
However I wouldn't recommend to use this solution, not only because of the boilerplate required, but because it relies heavily on the implementation details of the delegated properties and kotlin reflection.
I know that you can't use the delegated property syntax in Java, and won't get the convenience of "overriding" the set/get operators as in Kotlin, but I'd still like to use an existing property delegate in Java.
No, just like what you said in start, it does not exist in Java. But if you insist on doing it, you can do similar things.
public interface Delegate<T> {
T get();
void set(T value);
}
public class IntDelegate implements Delegate<Integer> {
private Integer value = null;
#Override
public void set(Integer value) {
this.value = value;
}
#Override
public Integer get() {
return value;
}
}
final Delegate<Integer> x = new IntDelegate();
Delcare x in interface allows you to have different implementation.

Java casting an object passed to method to its original type

I have a list called itemsData of object of class EtcStruct, but the class can differ depending on the file i want to use (the class is full of variables setters and getters):
ObservableList<EtcStruct> itemsData = FXCollections.observableArrayList();
Im passing it to the method thats supposed to work for any object type i choose and run invoked method from the file.
public static void parseToFile(ObservableList itemsData){
EtcStruct itemObject = (EtcStruct) itemsData.get(0);
System.out.print((int)reflectedmethod.invoke(itemObject);
}
Code above works , but what i want to achieve is make the method work without editing it's object type to make it more flexible for whatever structclass i plan to use.
I tried something with passing Struct Class name and .getClass() it returns the original type but i dont know what to do with it to make the new object of itemsData original type and cast the itemsData object.
public static void parseToFile(ObservableList itemsData,Class c){
Object itemObject = c.newInstance();
Object newobject = curClass.newInstance();
newobject = c.cast(itemsList.get(0));
}
Above seemed dumb to me and obviously didnt work.
After reading your comment I understand better why one would use reflection in your case. A GUI builder/editor is an example where reflection is used to provide an interface to set/get the values of components. Still, IMHO, reflection isn't a tool you would design for when you own the classes and are the primary designer. If possible you should strive for something more like this:
interface Parsable {
default int parse() {
System.out.println("Here I do something basic");
return 0;
}
}
class BasicStruct implements Parsable { }
class EtcStruct implements Parsable {
#Override
public int parse() {
System.out.println("Here I do something specific to an EtcStruct");
return 1;
}
}
// If some structs have a parent-child relationship
// you can alternatively `extend EtcStruct` for example.
class OtherStruct extends EtcStruct {
#Override
public int parse() {
super.parse();
System.out.println("Here I do something specific to an OtherStruct");
return 2;
}
}
void parseToFile(Parsable parsable) {
System.out.println(parsable.parse());
}
// If you use a generic with a specific class you don't
// have to guess or care which kind it is!
void parseToFile(ObservableList<Parsable> parsables) {
for (Parsable p : parsables) {
parseToFile(p);
}
}
public static void main(String[] args) {
ObservableList<Parsable> parsables = FXCollections.observableArrayList();
parsables.add(new BasicStruct());
parsables.add(new EtcStruct());
parsables.add(new OtherStruct());
parseToFile(parsables);
}
Output:
Here I do something basic
0
Here I do something specific to an EtcStruct
1
Here I do something specific to an EtcStruct
Here I do something specific to an OtherStruct
2
Of course, this is just an example that needs to be altered to meet your needs.
But what I still don't get is if you're able to parse from a file why you can't parse to one. Nonetheless, I slapped some code together to show you how I might parse an object to a file, manually, when dealing with Objects only.
The idea is to satisfy a bean-like contract. That is, each structure should provide a parameter-less constructor, all fields you want managed by reflection will follow Java naming convention and will have both a public setter and getter.
Don't get caught up in the file writing; that will be determined by your needs. Just notice that by following this convention I can treat any Object as a parsable structure. A less refined version here for reference:
public void parseToFile(Object object) throws IOException, InvocationTargetException, IllegalAccessException {
fos = new FileOutputStream("example" + object.getClass().getSimpleName());
List<Method> getters = Arrays.stream(object.getClass().getMethods())
.filter(method -> method.getName().startsWith("get") && !method.getName().endsWith("Class"))
.collect(Collectors.toList());
for (Method getter : getters) {
String methodName = getter.getName();
String key = String.valueOf(Character.toLowerCase(methodName.charAt(3))) +
methodName.substring(4, methodName.length());
fos.write((key + " : " + String.valueOf(getter.invoke(object)) + "\n").getBytes());
}
fos.close();
}
I think that you can just still use Generics to keep static objects typing. Try to parametrize your function parseToFile. Here is an example:
public static void parseToFile(ObservableList<EtcStruct> itemsData){
EtcStruct itemObject = itemsData.get(0);
System.out.print((int)reflectedmethod.invoke(itemObject);
}

Object-Oriented programming private class field + get / set or public class field?

I'm a junior developer (currently exercise Java) and I have one question about the correctness of my code, here is an example:
I am writing a simple MMO-game representation on Java, I have 2 classes (Character and spell).
Character has properties (mName, mHealth and mEnergy), Spell class has properties (mSpellName, mSpellCost, mSpellDamage). And Spell class also have a method called execute, here is a code
public void spellExecute(Character caster, Character target) {
caster.mEnergy -= this.spellCost;
target.mHealth -= this.spellDamage
}
This construction implies that Character fields are public and can be accessed directly, but in some examples I seen that all fields must be private and can be accessed only via get/set methods. My question is: Which way is more correct, in general? It's important to me because I wanna write a good code :)
Generally, you would use get/set methods, because they allow the class to control access, via those methods
Any other class which uses your class, should only be able to access and change your fields in the way you describe.
For example let's look at a simple (oversimplified) fuel pump
class Pump
{
constant int PRICE_PER_LITRE = 100; //in pence
private int litresDispensed;
private bool nozzleUp;
private int litresAvailable;
private int price; //in pence
construct()
{
litresDispensed = 0;
nozzleUp = false;
}
startFuelling()
{
nozzleUp = true;
}
stopFuelling()
{
nozzleUp = false;
}
takeFuel(int litresTaken)
{
if(nozzleUp = true)
{
litresAvailable -= litresTaken;
price += litresTaken * PRICE_PER_LITRE;
}
else
{
error("You must lift the nozzle before taking fuel!");
}
}
getPrice()
{
if(nozzleUp = true)
{
error("You can't pay until you've finished fuelling! Please return the nozzle");
}
else
{
return price;
}
}
}
Our final get method is important to ensure that the rest of the transaction is complete before the person tries to pay.
If we allowed direct access to the price, they could do it before they've finished taking fuel! And that would let them steal all our fuel.
As this shows, a get method protects the field from outside influence. It can still be manipulated, but only in the ways we want to allow it to be manipulated. Note also that there's no set method at all for this field: we don't want the user to be able to set their own price, only the one we dictate!
If you write get/set methods which only return and set the field, without any validation or checks, then you could simply make the field public (or, alternately, you need to decide whether that field should be accessed directly at all): that said, it's good practice to use get/set methods where possible, because it allows you to add validation in the future without breaking code.
You're right that it's important to write good code and at first getting the grasp of Object Oriented Programming can be a bit difficult.
In this case, I would recommend moving the spellExecute to a similar method, except on the Character class :
public void didUseSpell(Spell spell) {
this.mEnergy -= spell.spellCost;
}
public void wasHitBySpell(Spell spell) {
this.mHealth -= spell.spellDamage;
}
In your spell execute method, you would then call :
public void spellExecute(Character caster, Character target) {
caster.didUseSpell(this);
target.wasHitBySpell(this);
}
In general, there are many different was of solving this problem, and they all vary in terms of code cleanliness and verbosity. Another solution would be to create getter and setter methods for the fields that are affected by the spells.
Getters/setters are better, because it encapsulates or hides what the actual class is doing to set that data. Set the constructor private and let it initialize default values, then the user can call the set methods to set the variables.
Getters and setters with private fields is generally followed design choice. The reason is, you can guard your variables against unintentional changes from the clients using your API.
Consider this below example
public class Dummy{
public int age;
}
Now client can do this
new Dummy().age = -1
With setters and getters
public class Dummy{
private int age;
public void setAge(int age){
if (age < 0){
throw new RuntimeException("you are not allowed to do this");
}
......
}
Many frameworks for example Hibernate, IBATIS etc.. follow these naming conventions. Hope this answers your questions.
Getter and setter (Java bean) is more better.It also provide Encapsulation feature.Which is useful for hiding data.
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
Constructor is used for initialization the value when You are creating object.But If you want to set value of data after object creation then you must call setter behavior instead of call constructor.
Getters and setters are preferred - after all, why use an Object Orientated language if you're not going to use its main feature?
With setters in this situation you can easily enforce sanity rules without each caller having to duplicate the logic, e.g. - in Character try:
public void reduceMentalHealth(int val) {
if(this.mHealth > val) {
this.mHealth -= val;
} else {
this.mHealth = 0;
}
Without setters you would need this logic everywhere you changed the field. You could also include things like checking whether the Character is wearing a ring of mental invincibility in this method too :-)
Warning
You are mixing two related questions.
Questions:
[1] Should I use direct access fields, or fields access by accesors methods ( "getter" (s) and "setter" (s) ).
[2] In both cases, which access modifiers, should apply ?
Short Quick Answer
[1] Should I use direct access fields, or fields access by accesors methods ( "getter" (s) and "setter" (s) ).
Go, for the "fields access by accessor methods" a.k.a. "getter (s) and setter (s)". The other method is NOT wrong, it depends, what do you want to do.
[2] In both cases, which access modifiers, should apply ?
If you go for "plain fields", use "public", unless there is an specific reason to use "private" or "protected". If you go for "accesors methods", use "protected" for the fields, and "protected" or "public" for the accesors.
Long Boring Extended Answer
[1] Should I use direct access fields, or fields access by accesors methods ( "getter" (s) and "setter" (s) ).
Go, for the "fields access by accessor methods" a.k.a. "getter (s) and setter (s)".
The other method is NOT wrong, it depends, what do you want to do.
But, since property access can be overriden by those methods, that allows more features to be added, removed or changed by methods.
I suggest, leave "plain fields" for Data Objects.
[2] In both cases, which access modifiers, should apply ?
If you go for "plain fields", use "public", unless there is an specific reason to use "private" or "protected".
If you go for "accesors methods", use "protected" for the fields, and "protected" or "public" for the accesors.
Is not a good idea to apply "public" access for accesors' fields, because this way, you confuse yourself and other programmer users of your classes,
on which one to directly use.
Code Example:
public class ControlClass {
// example of non private field (s)
protected String controlname;
// ...
// example of non private field (s)
protected int width;
protected int height;
// ...
// example of read-only property
public final String getControlName()
{
return this.controlname;
} // String getControlName(...)
// ...
#Override
public int getWidth()
{
return this.width;
} // int getWidth(...)
#Override
public void setWidth(int newvalue)
{
this.width = newvalue;
} // void setWidth(...)
#Override
public int getHeight()
{
return this.height;
} // int getHeight(...)
#Override
public void setHeight(int newvalue)
{
this.height = newvalue;
} // void setHeight(...)
// ...
// constructor assigns initial values to properties' fields
public ControlClass(){
this.controlname = "control";
this.height = 0;
this.width = 0;
} // ControlClass(...)
// ...
} // class ControlClass
public class ButtonClass extends ControlClass {
// ...
// example of overriden public property with non public field
#Override
public int getWidth()
{
if (this.width < 5)
return 5
else
return this.width;
} // int getWidth(...)
// example of overriden public property with non public field
#Override
public void setWidth(int newvalue)
{
if (newvalue < 5)
throw new ArithmeticException("integer underflow");
this.width = newvalue;
} // void setWidth(...)
// example of overriden public property with non public field
#Override
public int getHeight()
{
if (this.height < 5)
return 5
else
return this.height;
} // int getHeight(...)
// example of overriden public property with non public field
#Override
public void setHeight(int newvalue)
{
if (newvalue < 5)
throw new ArithmeticException("integer underflow");
this.height = newvalue;
} // void setHeight(...)
// ...
// constructor assigns initial values to properties' fields
public ControlClass(){
this.controlname = "ButtonClass";
this.height = 5;
this.width = 5;
} // ButtonClass(...)
// ...
} // class ControlClass
I started to use "private" for fields, like many programmers, buy, eventually, had to change to "protected", because sometimes required to use it. directly.
Additional Comment.
I have work with other object oriented programming languages, with its own way and syntax for "properties", and that's give you another perspective.
Such as Object Pascal ( a.k.a. "Delphi" ), ECMAScript ( "Javascript" ), C++, C#. Note that Delphi and C#, supports "full properties", not just accesors methods or fields, and that's give developer another way of designing an Object and Class Oriented Software Application.
What does this has to do with Java ?
We'll when I design a Class in Java or C++, I design properties, the same way, as C# or Delphi, does, a concept that is independent of fields, or methods, even if there can be implemented by them.
Cheers.

Implementing a single Scala constructor that does more than set variables

Most of the time, a constructor for a class does nothing more than take its argument values and use them to set instance variables:
// Java
public class MyClass {
private int id;
public MyClass(int id) {
this.id = id;
}
}
So I understand the efficiency of Scala's default constructor syntax... simply declaring a list of variables in parentheses beside the class name:
// Scala
class MyClass(id: int) {
}
However, what about those circumstances where you need a constructor to actually DO STUFF, apart from simply plugging arguments into instance variables?
// Java
public class MyClass {
private String JDBC_URL = null;
private String JDBC_USER = null;
private String JDBC_PASSWORD = null;
public MyClass(String propertiesFilename) {
// Open a properties file, parse it, and use it to set instance variables.
// Log an error if the properties file is missing or can't be parsed.
// ...
}
}
How does this work in Scala? I can try to define an implementation for this constructor like so:
// Scala
class MyClass(propertiesFilename: String) {
def this(propertiesFilename: String) {
// parse the file, etc
}
}
... but I get a compilation error, complaining that the constructor is defined twice.
I could avoid this conflict by having a no-arg default constructor, and then declaring the above as an overloaded secondary constructor. However, what about situations in which you really DO need "one-and-only-one" constructor, and you need it to do stuff?
You can perform these actions simply in the class body.
Class Foo(filename: String) {
val index = {
val stream = openFile(filename)
readLines(stream)
...
someValue
}
println(“initialized...“)
}
Any code you put in the body of the class is executed at construction
class MyClass(propertiesFileName: String) {
println("Just created an instance of MyClass with properties in " + propertiesFileName)
val myFavoriteProperty = retrieveFavoriteFrom(propertiesFileName)
}
It may be a little awkward and it is certainly not a good idea to interleave your member declaration and your initialization code a lot, but it is a small price to pay for the the convenience of the variable initialization syntax

Enum "does not have a no-arg default constructor" with Jaxb and cxf

A client is having an issue running java2ws on some of their code, which uses & extends classes that are consumed from my SOAP web services. Confused yet? :)
I'm exposing a SOAP web service (JBoss5, Java 6). Someone is consuming that web service with Axis1 and creating a jar out of it with the data types and client stubs. They are then defining their own type, which extends one of my types. My type contains an enumeration.
class MyParent {
private MyEnumType myEnum;
// getters, settters for myEnum;
}
class TheirChild extends MyParent {
...
}
When they are running java2ws on their code (which extends my class), they get
Caused by: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
net.foo.bar.MyEnuMType does not have a no-arg default constructor.
this problem is related to the following location:
at net.foo.bar.MyEnumType
at public net.foo.bar.MyEnumType net.foo.bar.MyParent.getMyEnum()
The enum I've defined is below. This is now how it comes out after being consumed, but it's how I have it defined on the app server:
#XmlType(name = "MyEnumType")
#XmlEnum
public enum MyEnumType {
Val1("Val1"),
Val2("Val2")
private final String value;
MyEnumType(String v) {
value = v;
}
public String value() {
return value;
}
public static MyEnumType fromValue(String v) {
if (v == null || v.length() == 0) {
return null;
}
if (v.equals("Val1")) {
return MyEnumType.Val1;
}
if (v.equals("Val2")) {
return MyEnumType.Val2;
}
return null;
}
}
I've seen things online and other posts, like (this one) regarding Jaxb's inability to handle Lists or things like that, but I'm baffled about my enum. I'm pretty sure you can't have a default constructor for an enum (well, at least a public no-arg constructor, Java yells at me when I try), so I'm not sure what makes this error possible. Any ideas?
Also, the "2 counts of IllegalAnnotationsExceptions" may be because my code actually has two enums that are written similarly, but I left them out of this example for brevity.
The no-arg constructor for JAXB doesn't have to be public, it can be private:
private String value;
private MyEnumType() {} // for JAXB
MyEnumType(String v) {
value = v;
}
You can't keep the value member final this way, though.
I am certain you can have a default constructor for an enum.
In fact, that what you have when you don't define a constructor explicitely
(like yours with a String parameter).
You can also have several constructors, one no-args and others.
In the precise example you give, it would be simple to avoid the String parameter altogether.
The provided name() method has exactly the value you are provided.
The code would even be simpler:
#XmlType(name = "MyEnumType")
#XmlEnum
public enum MyEnumType {
Val1, Val2;
public String value() {
return name();
}
public static MyEnumType fromValue(String v) {
for(MyEnumType type : values()) {
if (type.value().equals(v)) {
return type;
}
}
return null;
}
}
If you have really some complex parameters to set to each value, and can't have specific constructors because of a library, you could also store your varying values into an EnumMap, and read this as needed.
when you do from-java-to-wsdl, apache check at first is it enum class or not, and only if this check fail, it check for constructor. You can see it in org.apache.axis.wsdl.fromJava.Types::isBeanCompatible. Any normal man, will think that if he write
public enum MyEnum{}
it will be enough. But Apache developers does not think so (IDK why, may be for some compatibility reasons). They do this method - org.apache.axis.utils.JavaUtils::isEnumClassSub.
If you will decomile this class, you will see, that your enum
MUST implement public String getValue() {return name();}
MUST implement public MyEnum fromString(String v){return valueOf(v);}
CAN'T contain public void setValue(){}
MUST implement String toString(), but each object implement it.

Categories