Java - Reflection: Get fields belonging to current class only - java

How can I get the fields associated only with the current class instead of all of its parent classes as well?
public class BaseClass()
{
public int x = 0;
}
public class AnotherClass() extends BaseClass
{
public int y = -1;
public int z = -2;
public void doStuff()
{
for(Field f : this.getClass().getFields())
{
//Save each field to a file
}
}
}
I want to get only Y and Z, which belong to AnotherClass. But the above gives me X as well.
This is meant to replace having to type each value that I want to save. It's not being saved in any typical format. It must be saved like this so don't suggest saving the fields in a different way.
Filtering out each field's name would defeat the purpose of this as there are well over 200.

You can get only the fields declared in the class with getDeclaredFields. It will exclude inherited fields.

You can filter based upon the Field's getDeclaredClass():
public static List<Field> fieldsDeclaredDirectlyIn(Class<?> c) {
final List<Field> l = new ArrayList<Field>();
for (Field f : c.getFields())
if (f.getDeclaringClass().equals(c))
l.add(f);
return l;
}
This picks just y and z for your example.

There may be a cleaner way to do this with flags to some function, but an obvious answer (and what I've done in the past) is to find the difference between the this.getClass().getFields() and the super.getClass().getFields() arrays.

Using public Field[] getDeclaredFields()
Returns an array of Field objects reflecting all the fields declared by the class or interface represented by this Class object. This includes public, protected, default (package) access, and private fields, but excludes inherited fields.
Field[] fields = AnotherClass.class.getDeclaredFields();
for(Field f : fields){
System.out.println(f.getName());
}

Related

Get types of all instance variables in Java

I have a class named Attributes, which has some instance variables as listed below:
public class Attributes {
protected A variable1;
protected B variable2;
protected C variables3;
/*
Getters and Setters of each method.
*/
}
I want the list of all instance variables' types present in the class.
The output: [A,B,C]
This contains all possible dataTypes present in this class.
Can someone please suggest a way?
NOTE: I've seen reflection, but I think it is useful only if we have filled the values for these variables and we want to fetch the values and names of those variables, not the types.
You simply can use the reflection method getType(). In order to get a list of all instance types it's as simple as:
Arrays.stream(Attributes.class.getDeclaredFields()).map(Field::getType).collect(Collectors.toList())
Where the getFields() will return the array of all the fields within the class (and not its instances, you are referencing the class and not the instance of the class).
The map() part will map the field to its class type.
And the collect(Collectors.toList()) will just get the stream result of Class<?> type to a List. If you don't want only the single class types, so no duplicates just use toSet() instead.
You can use reflection to access the Field and then get it's type:
See: Field.getType() && Class.getDeclaredFields()
You can use reflection to get the type like that:
class Scratch {
public static class Test {
private int a;
private long b;
}
public static void main(String[] args) {
Field[] fields = Test.class.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
System.out.println("Type: " + fields[i].getType());
}
}
}
Output:
Type: int
Type: long

What are the differences between Kotlin class properties and Java class fields

I've started to learn Kotlin. My current background is Java. I found out that class properties in Kotlin are quite different from class fields in Java, even though they look similar. In his question I would like to gather together all technical differences between those two. This is what I’ve already figured out:
Java field and hiding vs Kotli properties and overriding
(and actually this pushed me to write this post):
In Java, a field of a base class is hidden by a field with the same name in derived class, so which field is used depends on the type of a reference to the object which contains the field, not the type of the object itself (fields are not overridden like methods are, so they don't depend on runtime type of an object). For example this code:
class A {
public String name = "A";
public void printMessage() {
System.out.println("Field accessed in method declared inside class A invoked form an object of " + getClass() + " : " + name);
}
}
class B extends A{
public String name = "B";
}
public class Main {
public static void main(String... args){
B b = new B();
System.out.println("Field from instance of class B pointed by reference to B : " + b.name);
A a = b;
System.out.println("Field from instance of class B pointed by reference to A : "+a.name);
a.printMessage();
}
}
prints this :
Field from instance of class B pointed by reference to B : B
Field from instance of class B pointed by reference to A : A
Field accessed in method declared inside class A invoked form an object of class B : A
In contrast Kotlin properties are fields accessed by automatically generated getters and setters. Properties are overridden (not hidden), so property access is resolved at runtime, and the code with similar meaning as above written in Kotlin:
open class A {
open val name = "A"
fun printMessage() {
println("Field accessed in method declared inside class A invoked form an object of $javaClass : $name")
}
}
class B(override val name : String = "B") : A()
fun main(args : Array<String>) {
val b : B = B()
println("Field from instance of class B pointed by reference to B : " + b.name)
val a : A = b;
println("Field from instance of class B pointed by reference to A : " + a.name)
a.printMessage()
}
prints this :
Field from instance of class B pointed by reference to B : B
Field from instance of class B pointed by reference to A : B
Field accessed in method declared inside class A invoked form an object of class B : B
Access level
Java fields are package – private by default. Kotlin properties are public by default.
Default initialization
Java fields are initialized with reasonable default values (as describet here : https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html).
Every Kotlin class property has to be created in a way which will allow it to provide explicitly given value when it will be accessed.
One can achieve this by initiallizer, constructor, setter, lazy initialization:
class InitValues(val inCtor : String = "Given in constructor"){
var byInitializer = "In initializer"
var initializedWithNull : String? = null
val valueGivenByGetter
get() : String {
return "This value is given by getter"
}
val byLazyInit : String by lazy { "This is lazy init" }
}
but value which should be returned has to be given – no defaults will be provided.
Are there any other technical differences regarding class fields / properties which may surprise Java programmer writing code in Kotlin?
(I’m not talking about additional features like for example delegated properties but those things which at first glance are similar to what exists in Java and can be delusive)
I would like to elaborate more on the differences between a Java field and a Kotlin Property. Have a look at the following examples of Java field and Kotlin property.
Examples
Java field:
class Product {
public int discount = 20;
}
Kotlin property:
class Product {
var discount: Int = 20
}
Auto-generated Accessors
The two examples above are not equivalent. Because in Kotlin, getters and setters are auto-generated for the properties. The Kotlin property above is equivalent to the following Java code:
class Product {
private int discount = 20;
public int getDiscount() {
return discount;
}
public void setDiscount(int discount) {
this.discount = discount;
}
}
So the difference between the Java field and Kotlin Property is that the Kotlin property creates a field and its accessors. When the property is a val, it creates a getter only. When the property is a var, it creates both a getter and a setter. And the field becomes private by default as shown in the above code, the discount is private. But you can access the discount using its getters and setters.
Custom Accessors
What if we want to implement some logic or validation inside the getters and setters in Kotlin? For example, when someone is setting the discount on the product, we want to make sure it's never above 85%. In this case, we can define the custom accessors for the discount property like following:
class Product {
var discount: Int = 20
set(value) {
if (value >= 85) {
field = 85
} else {
field = value
}
}
}
The field is a reserved keyword in Kotlin which holds the value as a backing field. The above code result in:
product.discount = 70;
println(product.discount) // 70
product.discount = 90;
println(product.discount) // 85
We can do similar things with the getter using the get() method.
That's it! Hope that helps.

Get a field's value

I want to get the value with which the field is being initialized.
Example:
class ClassA {
public String someString = "Merry Christmas";
}
class ClassB {
String anotherString = ClassA.class.getField("someString");
}
Is there any way to do this?
This would be possible if ClassA.string were static. In this case you would be able to get the value through reflection without the need to get a hold of an instance of ClassA inside of which someString is defined:
class ClassA {
public static String someString = "Merry Christmas";
}
...
Object s = ClassA.class.getField("someString").get(null);
Demo 1.
If the variable is not static, and you simply want to get its initial value, you could still do it, assuming that ClassA has a default constructor:
public static void demo(Class<?> cl) throws Exception {
Object s = cl.getField("someString").get(cl.newInstance());
System.out.println(s);
}
Demo 2.
You first have to create an instance o ClassA into ClassB:
ClassA a = new ClassA();
System.out.println(a.someString);
But according to the current format of your code, the best option would be declaring someString static: public static String someString = "Merry Christmas";. Then you can directly access this field from any other class of any package (as it's public):
System.out.println(ClassA.someString);
I think you do not fully understand what a (non-static) field means: it means the field has a specific value for each instance (object) of ClassA, so you cannot access the fields content, because there can be thousands, each with a different value.
There are several options:
A possible solution is to make the field static:
ClassA {
public static String someString = "Merry Christmas";
}
ClassB {
String anotherString = ClassA.someString;
}
Or as #toubou says, you can construct an object and access the field of that specific object. Note however that fields represent an object's state, and therefore can modify.

Accessing a Super's Member of different type with the same variable name

Consider the following superclass and subclass pair, how do you access the superclass member?
class Super {
Number aNumber;
}
class Subbie extends Super {
Float aNumber;
}
You can access the super Member by super.aNumber provided it is an instance of the Subclass.
Given that the attribute does not have a visiblity modifier, it is assumed to be package private. Subbie will only be able to access Super's aNumber if they're in the same package.
If it was, you could access it like this: super.aNumber. Notice super here is a keyword that implicitly refers to the superclass, and doesn't have anything to do with the superclass being named Super.
class Super {
Number aNumber;
}
class Subbie extends Super {
Float aNumber;
public Number getNumberFromSuper() {
return super.aNumber;
}
}
I'd suggest to take a read on the excellent Java tutorials online, for instance:
Inheritance
Controlling Access to Members of a Class
You can define a field with different keywords known as Access Modifiers (check the links at the end for a detailed explanation on this topic), each one defining a scope for access/use. I'll focus this explanation on fields.
Public: Accessible by everyone. This Access Modifier is regulary used with methods and not with fields. In Java, it is encouraged the use of get and set methods to access the value of a field and change it (respectively). You can access a field this way:
AClass c = new AClass();
c.publicField = 3; //Setting a value in a field, int in this case
int sum = c.publicField + 4; //Obtaining the value of publicField to use it
Private: Definining a field as private makes it visible only to the class itself, meaning no one outside the boundaries of a class will be able to see that field. A common class in Java usually has private fields and accessors (get & set methods).
public class AClass {
public int publicField;
private String privateField = "Can't see me!";
public String getPrivateField() {
return privateField;
}
public void setPrivateField(String newValue) {
privateField = newVaule;
}
}
Getters and Setters let you control the access to your private fields, allowing you to perform any logic you desire before updating the value of that field or preparing a field in a particular before returning its value if you need it.
Protected: Only subclasses of a class and classes in the same package can access a field defined with this keyword. In your case Subbie has access to the protected fields of Super and any other class in the same package as Super has access to those fields as well.
No Access Modifier: This is your current case and the answer to your question relies strongly on the structure of your classes. If they are in the same package, then you can access Super's field from Subbie. Otherwise, if Subbie is in another package, you won't be able to access that field. This field is referenced as Package-Private.
Some related articles you might want to check:
Inheritance in Java
Controlling the Access to Members of a Class

Getting value of public static final field/property of a class in Java via reflection

Say I have a class:
public class R {
public static final int _1st = 0x334455;
}
How can I get the value of the "_1st" via reflection?
First retrieve the field property of the class, then you can retrieve the value. If you know the type you can use one of the get methods with null (for static fields only, in fact with a static field the argument passed to the get method is ignored entirely). Otherwise you can use getType and write an appropriate switch as below:
Field f = R.class.getField("_1st");
Class<?> t = f.getType();
if(t == int.class){
System.out.println(f.getInt(null));
}else if(t == double.class){
System.out.println(f.getDouble(null));
}...
R.class.getField("_1st").get(null);
Exception handling is left as an exercise for the reader.
Basically you get the field like any other via reflection, but when you call the get method you pass in a null since there is no instance to act on.
This works for all static fields, regardless of their being final. If the field is not public, you need to call setAccessible(true) on it first, and of course the SecurityManager has to allow all of this.
I was following the same route (looking through the generated R class) and then I had this awful feeling it was probably a function in the Resources class. I was right.
Found this:
Resources::getIdentifier
Thought it might save people some time. Although they say its discouraged in the docs, which is not too surprising.
I was looking for how to get a private static field and landed here.
For fellow searchers, here is how:
public class R {
private static final int _1st = 0x334455;
}
class ReflectionHacking {
public static main(String[] args) {
Field field = R.class.getFieldDeclaration("_1st");
field.setAccessible(true);
int privateHidenInt = (Integer)field.get(null);
}
}

Categories

Resources