Kotlin - equivalence to SomeClass.class for objects? - java

I'm trying to statically get an object's name (For logging uses)
The equivalence for:
public class SomeClass
{
private static final String TAG = SomeClass.class.getSimpleName()
}
In Kotlin:
object SomeObject
{
private const val TAG = ?
}

Try this
SomeClass::class.simpleName

If you are using it in Android application, i would suggest you to do it like following: (packageName:className)
object SomeObject
{
private val TAG = "${SomeObject::class.java.`package`.name}:${SomeObject::class.simpleName}"
}
Doing so you can ensure that tag name for any other class wont be duplicate.
It is really helpful, if you are creating a lib/code snippet that someone can use. Otherwise having same tag name may lead to runtime errors.

Related

Java nested enum understanding

I want to ask about nested enums. I am working with old code and i found very strange construction that i not really good understand.
I have this enum :
public enum DbEngines {
ORACLE("oracle", "set define on", "set define off")
, POSTGRESQL("postgresql", "--TODO set define on", "--TODO set define off");
private final String dbEngine;
private String setOn;
private String setOff;
DbEngines(String dbEngine, String setOn, String setOff) {
this.dbEngine = dbEngine;
this.setOn = setOn;
this.setOff = setOff;
}
public String getSetOn() {
return setOn;
}
public String getSetOff() {
return setOff;
}
public String toString() {
return this.dbEngine;
}
}
I added private String to this enum, that are engine specific, so it is good place for me here. The problem is, that in some places in method declaration i see something like that
public someMethod(Enum<DbEngines> engine, ...)
And it worked perfectly without methods, but now, after changing, I couldn't call public getters of this enum. But if i change to :
public someMethod(DbEngines engine, ...)
it works without any problems with all public getters. Maybe someone could explain that?
Enum in Java is the base class for all enumeration types. One can think of it as similar to Object class.
Just like one can hold reference of object of any class using the reference of type Object, one can refer to an enumeration type using the reference of type Enum.
Object o = new Integer(10);
Enum e = DBEngine.ORACLE;
One cannot invoke a method present in inherited class but absent in superclass using the reference of superclass.
Similar explanation over here.

Kotlin: Java can't resolve Kotlin Symbol?

I have a Kotlin Code just like the below, SingleKotlin.instance can be called by the other Kotlin files
class SingleKotlin private constructor(){
companion object {
val instance by lazy {
SingleKotlin()
}
}
}
However, when I try to call SingleKotlin.instance from java, it shows can't resolve symbol 'instance'
I don't understand why, anybody can explian and how can I solve this problem?
Just add #JvmStatic annotation above field (as said in this documentation https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#static-fields)
So, your code should be like this:
class SingleKotlin private constructor(){
companion object {
#JvmStatic
val instance by lazy {
SingleKotlin()
}
}
}
And now you can call it like
SingleKotlin.instance
In addition to #YuriiKyrylchuk's answer: another option (and the only option if you don't have control over the Kotlin code) is to refer to MyClass.Companion from Java. Example:
class MyClass {
companion object {
val x: Int = 0
}
}
And in Java:
MyClass.Companion.getX();
If your SingleKotlin object has a single private constructor without parameters, you can use object instead:
object SingleKotlin {
// some members of SingleKotlin
val x = 42
}
Then in Java you reference it through the INSTANCE static field:
SingleKotlin single = SingleKotlin.INSTANCE;
// or
SingleKotlin.INSTANCE.getX();
You need to call the method from Java like this:
AppUIUtils.Companion.yourMethod()
In additional to Ilya answer you can use #JvmStatic annotation
object SingleKotlin {
// some members of SingleKotlin
#JvmStatic val x = 42
}
Then in Java
SingleKotlin.getX();

Android: how to get an instance of a member field via reflection

Here's a fairly convoluted question. I am trying to access the webviewcore instance member of a webview via reflection. I want a reference to the webviewcore that is used by my webview, so that i can invoke a method that the webviewcore uses. I have to do this via reflection because the public sdk does not let you access this class. I know using reflection to do this is discouraged but i've made my peace with that.
I've read here that to achieve this i would do something like this:
Class aClass = MyObject.class
Field field = aClass.getField("someField");
MyObject objectInstance = new MyObject();
Object value = field.get(objectInstance);
field.set(objetInstance, value);
The problem with doing this (and maybe im misunderstanding this) is that it looks like i have to create a new instance of the WebViewCore to work with and then set it back to my instance. First and formost, am i understanding this correctly. If so, then can someone translate the code above to do what i am looking for it to do. If my understanding is incorrect, does anyone know how else i can access the WebViewCore of an instance of a webview?
Thanks!
EDIT: Due to confusion i will restate my question. I have an instance of a webview. That webview has a member field called 'mWebViewCore' which is an instance of the WebViewCore class. The WebViewCore has a member class called called TextSelectionData. I need to access the the TextSelectionData object via reflection. I know how to access fields and methods of the webview through reflection. So i can get mWebViewCore field, but i don't know how to take that field and access it's fields, methods, classes etc. The broadstrokes are take an instance of an object, find a specific field in that instance, and access the fields of that field.
Sorry for the confusion. It come from my weak understanding of reflection, and partially from the fact that i didn't adequately understand WebViewCore class. here's where i've gotten to in the code:
Class c = mWebView.getClass();
try {
Field webViewCoreField = c.getDeclaredField("mWebViewCore");
webViewCoreField.setAccessible(true);
//how do i get the fields of webViewCoreField?
}
Assuming a WebViewCore with a private String s field:
public class WebViewCore {
private String s;
public WebViewCore(String s) { this.s = s; }
#Override
public String toString() {
return "WebViewCore{" + "s='" + s + '\'' + '}';
}
}
Assuming a WebView with a private WebViewCore webViewCore field:
public class WebView {
private WebViewCore webViewCore;
public WebView() { webViewCore = new WebViewCore("ohai"); }
}
Now we reflect:
public class Main {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
// First get the private WebViewCore field...
Field fWvc = WebView.class.getDeclaredField("webViewCore");
fWvc.setAccessible(true);
System.out.println(fWvc);
// Then get an instance of a WebView; you already have one,
// I'm constructing one...
WebView wv = new WebView();
WebViewCore wvc = (WebViewCore) fWvc.get(wv);
System.out.println(wvc);
// Now get the private String field from the WebViewCore class...
Field fS = WebViewCore.class.getDeclaredField("s");
fS.setAccessible(true);
System.out.println(fS);
// Now get the value of the private String field from the instance
// of the WebViewCore we retrieved above...
String s = (String) fS.get(wvc);
System.out.println(s);
}
}
So, here's my rant: reflection is a relatively advanced technique, although it's pretty straight-forward. (With the caveat I've been doing this for a really long time, with languages that have better reflective abilities than Java.)
This seems to still be a bit out-of-reach--that being the case, I'd be really, really careful about using it, and would avoid it at essentially any cost. I question your need to do whatever it is you're trying to do, and after that, I'd question the wisdom of doing whatever it is you're trying to, until stuff like the toy example we're mucking with here causes zero conceptual issues.
Here there be dragons, and they will cook and eat you.
Reflection offers you ability to access private fields, private methods of a class(or rather, an object), and runtime informations.
Your understanding of reflection is correct. But in the code snippet you posted, your use of reflection does not make sense to me. You are setting a value to a field with a value from that field, i.e. you are doing something like:
obj.setValue(obj.getValue());
You said you wanted to access a private field of WebView, I assume you already have the WebView instance, so once you get the Field reference, you just set the value of that field on your original WebView instance, you don't and shouldn't create a new WebView object, because it was the original WebView object that you wanted to operate on.
Something like this:
WebView myWebView = ...;
Object myValueToSet = ...;
Class webViewClass = WebView.class
Field field = webViewClass.getField("someField");
field.setAccessible(true);
field.set(myWebView, myValueToSet);

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

How to read the value of a private field from a different class in Java?

I have a poorly designed class in a 3rd-party JAR and I need to access one of its private fields. For example,
why should I need to choose private field is it necessary?
class IWasDesignedPoorly {
private Hashtable stuffIWant;
}
IWasDesignedPoorly obj = ...;
How can I use reflection to get the value of stuffIWant?
In order to access private fields, you need to get them from the class's declared fields and then make them accessible:
Field f = obj.getClass().getDeclaredField("stuffIWant"); //NoSuchFieldException
f.setAccessible(true);
Hashtable iWantThis = (Hashtable) f.get(obj); //IllegalAccessException
EDIT: as has been commented by aperkins, both accessing the field, setting it as accessible and retrieving the value can throw Exceptions, although the only checked exceptions you need to be mindful of are commented above.
The NoSuchFieldException would be thrown if you asked for a field by a name which did not correspond to a declared field.
obj.getClass().getDeclaredField("misspelled"); //will throw NoSuchFieldException
The IllegalAccessException would be thrown if the field was not accessible (for example, if it is private and has not been made accessible via missing out the f.setAccessible(true) line.
The RuntimeExceptions which may be thrown are either SecurityExceptions (if the JVM's SecurityManager will not allow you to change a field's accessibility), or IllegalArgumentExceptions, if you try and access the field on an object not of the field's class's type:
f.get("BOB"); //will throw IllegalArgumentException, as String is of the wrong type
Try FieldUtils from Apache commons-lang3:
FieldUtils.readField(object, fieldName, true);
P.S. In my opinion, reflection is evil.
Reflection isn't the only way to resolve your issue (which is to access the private functionality/behaviour of a class/component)
An alternative solution is to extract the class from the .jar, decompile it using (say) Jode or Jad, change the field (or add an accessor), and recompile it against the original .jar. Then put the new .class ahead of the .jar in the classpath, or reinsert it in the .jar. (the jar utility allows you to extract and reinsert to an existing .jar)
As noted below, this resolves the wider issue of accessing/changing private state rather than simply accessing/changing a field.
This requires the .jar not to be signed, of course.
One other option that hasn't been mentioned yet: use Groovy. Groovy allows you to access private instance variables as a side effect of the design of the language. Whether or not you have a getter for the field, you can just use
def obj = new IWasDesignedPoorly()
def hashTable = obj.getStuffIWant()
Using the Reflection in Java you can access all the private/public fields and methods of one class to another .But as per the Oracle documentation in the section drawbacks they recommended that :
"Since reflection allows code to perform operations that would be illegal in non-reflective code, such as accessing private fields and methods, the use of reflection can result in unexpected side-effects, which may render code dysfunctional and may destroy portability. Reflective code breaks abstractions and therefore may change behavior with upgrades of the platform"
here is following code snapts to demonstrate basic concepts of Reflection
Reflection1.java
public class Reflection1{
private int i = 10;
public void methoda()
{
System.out.println("method1");
}
public void methodb()
{
System.out.println("method2");
}
public void methodc()
{
System.out.println("method3");
}
}
Reflection2.java
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Reflection2{
public static void main(String ar[]) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
{
Method[] mthd = Reflection1.class.getMethods(); // for axis the methods
Field[] fld = Reflection1.class.getDeclaredFields(); // for axis the fields
// Loop for get all the methods in class
for(Method mthd1:mthd)
{
System.out.println("method :"+mthd1.getName());
System.out.println("parametes :"+mthd1.getReturnType());
}
// Loop for get all the Field in class
for(Field fld1:fld)
{
fld1.setAccessible(true);
System.out.println("field :"+fld1.getName());
System.out.println("type :"+fld1.getType());
System.out.println("value :"+fld1.getInt(new Reflaction1()));
}
}
}
Hope it will help.
As oxbow_lakes mentions, you can use reflection to get around the access restrictions (assuming your SecurityManager will let you).
That said, if this class is so badly designed that it makes you resort to such hackery, maybe you should look for an alternative. Sure this little hack might be saving you a few hours now, but how much will it cost you down the road?
Java 9 introduced Variable Handles. You can access a private field of a class using them.
The code for your example will look like following:
var lookup = MethodHandles.lookup();
var handle = MethodHandles
.privateLookupIn(IWasDesignedPoorly.class, lookup)
.findVarHandle(IWasDesignedPoorly.class, "stuffIWant", Hashtable.class);
var value = handle.get(obj);
It is also advisable to use Lookup and VarHandle objects as static final fields.
Use the Soot Java Optimization framework to directly modify the bytecode.
http://www.sable.mcgill.ca/soot/
Soot is completely written in Java and works with new Java versions.
If using Spring:
In a testing context, ReflectionTestUtils provides some handy tools that can help out here with minimal effort. It's described as being "for use in unit and integration testing scenarios".
In a non-testing context, there is also a similar class named ReflectionUtils but this is described as "Only intended for internal use" - see this answer for a good interpretation of what this means.
To address the example in the original post:
Hashtable iWantThis = (Hashtable)ReflectionTestUtils.getField(obj, "stuffIWant");
You need to do the following:
private static Field getField(Class<?> cls, String fieldName) {
for (Class<?> c = cls; c != null; c = c.getSuperclass()) {
try {
final Field field = c.getDeclaredField(fieldName);
field.setAccessible(true);
return field;
} catch (final NoSuchFieldException e) {
// Try parent
} catch (Exception e) {
throw new IllegalArgumentException(
"Cannot access field " + cls.getName() + "." + fieldName, e);
}
}
throw new IllegalArgumentException(
"Cannot find field " + cls.getName() + "." + fieldName);
}
You can use jOOR for that.
class Foo {
private final String value = "ABC";
}
class Bar {
private final Foo foo = new Foo();
public String value() {
return org.joor.Reflect
.on(this.foo)
.field("value")
.get();
}
}
class BarTest {
#Test
void accessPrivateField() {
Assertions.assertEquals(new Bar().value(), "ABC");
}
}
Just an additional note about reflection: I have observed in some special cases, when several classes with the same name exist in different packages, that reflection as used in the top answer may fail to pick the correct class from the object. So if you know what is the package.class of the object, then it's better to access its private field values as follows:
org.deeplearning4j.nn.layers.BaseOutputLayer ll = (org.deeplearning4j.nn.layers.BaseOutputLayer) model.getLayer(0);
Field f = Class.forName("org.deeplearning4j.nn.layers.BaseOutputLayer").getDeclaredField("solver");
f.setAccessible(true);
Solver s = (Solver) f.get(ll);
(This is the example class that was not working for me)
It is quite easy with the tool XrayInterface. Just define the missing getters/setters, e.g.
interface BetterDesigned {
Hashtable getStuffIWant(); //is mapped by convention to stuffIWant
}
and xray your poor designed project:
IWasDesignedPoorly obj = new IWasDesignedPoorly();
BetterDesigned better = ...;
System.out.println(better.getStuffIWant());
Internally this relies on reflection.
Try to go around the problem for the case, the calass of which you want to set/get data is one of your own classes.
Just create a public setter(Field f, Object value) and public Object getter(Field f) for that. You can even do some securoty check on your own inside theses member functions. E.g. for the setter:
class myClassName {
private String aString;
public set(Field field, Object value) {
// (A) do some checkings here for security
// (B) set the value
field.set(this, value);
}
}
Of course, now you have to find out the java.lang.reflect.Field for sString prior to setting of field value.
I do use this technique in a generic ResultSet-to-and-from-model-mapper.

Categories