Thursday, 17 August 2017

How to convert String to Date in Java

When you are displaying date you will convert date to String in required format and print it. But you may need to convert it to date again if -

  1. You have to do any date calculation.
  2. You want to convert date from one format to another. In that case you do need to first convert String date to a date using the same pattern as is used for string and then convert the date again to String in another format.

Using SimpleDateFormat

A tried and tested way to convert String to java.util.Date is to use SimpleDateFormat which also gives you an option to provide customized format. For converting Date to String you use the format method where as to convert from String to Date you will have to use parse method.

Steps to follow

  1. Once you have a date String in a given format you need to create an object of SimpleDateFormat passing pattern as argument which should be similar to the pattern used in the date String.

  2. Call parse method passing date string as an argument which returns the parsed date.

Example code

Let’s see some examples using date strings with different patterns.

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class StringToDate {
 public static void main(String[] args) {
  
  String strDate = "30/06/2017";
  getDate(strDate, "dd/MM/yyyy");
  
  strDate = "Sun, May 8, '16";
  getDate(strDate, "EEE, MMM d, ''yy");
  
  strDate = "Sunday, May 08, 2016";
  getDate(strDate, "EEEE, MMMM dd, yyyy");
  
  strDate = "2016-05-08 AD at 10:13:46 IST";
  getDate(strDate, "yyyy-MM-dd G 'at' hh:mm:ss z");
  
  strDate = "2017-08-12T20:17:46.384Z";
  strDate = strDate.replaceAll("Z", "+0530");
  getDate(strDate, "yyyy-MM-dd'T'hh:mm:ss.SSSZ");
  
 }
 
 private static void getDate(String strDate, String pattern){
  SimpleDateFormat formatter = new SimpleDateFormat(pattern);
  try {
   Date date = formatter.parse(strDate);
   System.out.println("Parsed date " + date);
  } catch (ParseException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
}

Output

Parsed date Fri Jun 30 00:00:00 IST 2017
Parsed date Sun May 08 00:00:00 IST 2016
Parsed date Sun May 08 00:00:00 IST 2016
Parsed date Sun May 08 10:13:46 IST 2016
Parsed date Sat Aug 12 20:17:46 IST 2017

Here note that for the date strDate = "2017-08-12T20:17:46.384Z"; where 'Z' literal is used with the date, you need to remove that literal, it won’t be parsed otherwise and throw exception as follows –

java.text.ParseException: Unparseable date: "2017-08-12T20:17:46.384Z"
 at java.text.DateFormat.parse(Unknown Source)
 at org.netjs.prgrm.StringToDate.getDate(StringToDate.java:31)
 at org.netjs.prgrm.StringToDate.main(StringToDate.java:24)

Here, while replacing it, I have replaced it with the difference with the GMT time i.e. 5 Hrs. 30 Mins (For India). You can replace it with the time zone offset of your requirement or you can find that difference from GMT programmatically.

Converting from one String date format to another

It may happen that you get the date in String format and you have to convert it another format. In that case also first convert the String to date and then again to String in another format.

Example code

Suppose you get the String date in the format dd/MM/yyyy which you will have to convert to format yyyy-MM-dd.

public class StringToDate {
 public static void main(String[] args) {
  
  String strDate = "30/06/2017";
  System.out.println("date in old format - " + strDate);
  SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
  try {
   Date date = formatter.parse(strDate);
   System.out.println("Parsed date - " + date);
   
   formatter = new SimpleDateFormat("yyyy-MM-dd");
   System.out.println("date in new format - " + formatter.format(date));
  } catch (ParseException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  
  
 }
}

Output

date in old format - 30/06/2017
Parsed date - Fri Jun 30 00:00:00 IST 2017
date in new format - 2017-06-30

Using DateFormatter of new Java date time API – Java 8

If you are using Java 8 then you do have better option to convert String to date. If you have an object of type LocalDate, LocalTime or LocalDateTime you can format it using the parse method.

There are two overloaded parse methods :

  • parse(CharSequence text) – Here text argument denotes the date string that has to be parsed. This parse method uses standard ISO_LOCAL_DATE formatter.
  • parse(CharSequence text, DateTimeFormatter formatter) – In this variant of parse method you can pass custom formatter.

Example code

Let’s see some examples with different formats.

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;


public class String2Date {

 public static void main(String[] args) {
  try{
   String strDate = "2011-12-03T10:15:30";
   LocalDateTime localDateTime = LocalDateTime.parse(strDate);
   System.out.println("date " + localDateTime);
   
   strDate = "30/06/2017";
   LocalDate localDate = LocalDate.parse(strDate, 
                           DateTimeFormatter.ofPattern("dd/MM/yyyy"));
   System.out.println("date " + localDate);
   
   strDate = "Sun, May 8, '16";
   localDate = LocalDate.parse(strDate, 
                           DateTimeFormatter.ofPattern("EEE, MMM d, ''yy"));
   System.out.println("date " + localDate);
   
   strDate = "2017-08-12T20:17:46.384Z";
   localDateTime = LocalDateTime.parse(strDate, 
                           DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSz"));
   System.out.println("date " + localDateTime);
   
   strDate = "2016-05-08 AD at 10:13:46 IST";
   localDateTime = LocalDateTime.parse(strDate, 
                           DateTimeFormatter.ofPattern("yyyy-MM-dd G 'at' HH:mm:ss z"));
   System.out.println("date " + localDateTime);
   
   strDate = "2017-08-15 03:32:12-0400";  
   ZonedDateTime zonedDateTime = ZonedDateTime.parse(strDate, 
                           DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ssxx"));
   System.out.println("date " + zonedDateTime);
  }catch(DateTimeParseException ex){
   ex.printStackTrace();
  }
  
 }
}

Output

date 2011-12-03T10:15:30
date 2017-06-30
date 2016-05-08
date 2017-08-12T20:17:46.384
date 2016-05-08T10:13:46
date 2017-08-15T03:32:12-04:00

Here note that, for the date time with zone offset strDate = "2017-08-15 03:32:12-0400"; ZonedDateTime is used to correctly parse the string.

That's all for this topic How to convert String to Date in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. How to convert Date to String in Java
  2. How to find last modified date of a file in Java
  3. How to read file from the last line in Java

You may also like -

>>>Go to Java Programs page

Tuesday, 15 August 2017

How to convert Date to String in Java

In most of the Java application it’s a very common requirement to print date in a required format. For that you do need to convert date to a String that is in the required format. In this post we’ll see options to convert date to String.

Using SimpleDateFormat

A tried and tested way to convert date to string is to use SimpleDateFormat which also gives you an option to provide customized format.

SimpleDateFormat resides in java.text package and extends DateFormat class which is an abstract class. DateFormat class also provides predefined styles to format dates and times.

Here note that SimpleDateFormat is not thread safe so not safe to use in multi-threaded application with out proper synchronization. An alternative way is to use ThreadLocal class, see an example of how ThreadLocal can be used by storing separate instance of SimpleDateFormat for each thread here.

When you create a SimpleDateFormat object, you specify a pattern String. The contents of the pattern String determine the format of the date and time.

Example code

Let’s see an example to convert date to String using the given format.

In this example there is a method getFormattedDate() where pattern is passed as an argument. Date is converted to String using the passed pattern.

import java.text.SimpleDateFormat;
import java.util.Date;

public class FormatDate {

 public static void main(String[] args) {
  FormatDate fd = new FormatDate();
  
  // For date in format Wed, Jun 8, '16
  fd.getFormattedDate("EEE, MMM d, ''yy");

  // For date in format Wednesday, June 08, 2016
  fd.getFormattedDate("EEEE, MMMM dd, yyyy");

  // For date in format 05/08/2016
  fd.getFormattedDate("MM/dd/yyyy");

  // For date in format 08/05/2016
  fd.getFormattedDate("dd/MM/yyyy");
  
  // Only time like 21:52:14:096 PM
  // in 24 hr format, with mili seconds and AM/PM marker
  fd.getFormattedDate("HH:mm:ss:SSS a");

 }
 
 /**
  * 
  * @param pattern
  */
 public void getFormattedDate(String pattern){
  Date today;
  String result;
  SimpleDateFormat formatter;
  // Creating the date format using the given pattern
  formatter = new SimpleDateFormat(pattern);
  // Getting the date instance
  today = new Date();
  // formatting the date
  result = formatter.format(today);
  System.out.println("Pattern: " + pattern + 
    " Formatted Date - " + result);
 }

}

Output

Pattern: EEE, MMM d, ''yy Formatted Date - Sun, Aug 13, '17
Pattern: EEEE, MMMM dd, yyyy Formatted Date - Sunday, August 13, 2017
Pattern: MM/dd/yyyy Formatted Date - 08/13/2017
Pattern: dd/MM/yyyy Formatted Date - 13/08/2017
Pattern: HH:mm:ss:SSS a Formatted Date - 12:50:14:097 PM

Using DateFormatter of new Java Date & Time API – Java 8

From Java 8 there is another option to convert date to a string in required format. If you have an object of type LocalDate, LocalTime or LocalDateTime you can format it using the DateFormatter class. All these classes reside in java.time package.

All these classes LocalDate, LocalTime or LocalDateTime have format method that takes object of DateFormatter class as argument. Using that object of DateFormatter format for conversion can be provided.

You can use static methods ofLocalizedDate(FormatStyle dateStyle), ofLocalizedTime(FormatStyle dateStyle) or ofLocalizedDateTime(FormatStyle dateStyle) based on the type of object you are using to provide the pattern for formatting. Here FormatStyle is an Enumeration with the following Enum constants. Note that these methods return a locale specific date-time formatter.
  • public static final FormatStyle FULL - Full text style, with the most detail. For example, the format might be 'Tuesday, April 12, 1952 AD' or '3:30:42pm PST'.
  • public static final FormatStyle LONG - Long text style, with lots of detail. For example, the format might be 'January 12, 1952'.
  • public static final FormatStyle MEDIUM - Medium text style, with some detail. For example, the format might ' be 'Jan 12, 1952'.
  • public static final FormatStyle SHORT - Short text style, typically numeric. For example, the format might be '12.13.52' or '3:30pm'.

Example Code

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;

public class DateToString {

 public static void main(String[] args) {
  LocalDateTime curDateTime = LocalDateTime.now();
  System.out.println("Date before formatting " + curDateTime);
  String strDate =  getFormattedDate(curDateTime);
  System.out.println("Formatted date - " + strDate); 
 }
 
 private static String getFormattedDate(LocalDateTime dt){
  DateTimeFormatter df1 = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);
  //DateTimeFormatter df1 = DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG);
  //DateTimeFormatter df1 = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM);
  //DateTimeFormatter df1 = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT);
  return dt.format(df1);
 }

}

Output for FULL

Date before formatting 2017-08-13T20:08:25.056
Formatted date - Sunday, 13 August, 2017

Output for LONG

Date before formatting 2017-08-13T20:08:54.921
Formatted date - 13 August, 2017

Output for MEDIUM

Date before formatting 2017-08-13T20:09:27.308
Formatted date - 13 Aug, 2017

Output for SHORT

Date before formatting 2017-08-13T20:09:53.465
Formatted date – 13/8/17

Using ofPattern() method

You can also use ofPattern() method to provide the pattern for formatting. Using this method you can provide custom format.

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;


public class DateToString {

 public static void main(String[] args) {
  LocalDateTime curDateTime = LocalDateTime.now();
  System.out.println("Date before formatting " + curDateTime);
  // Passing custom pattern
  getFormattedDate(curDateTime, "dd/MM/yyyy");
  //String strDate =  getFormattedDate(curDateTime);
  //System.out.println("Formatted date - " + strDate);
  
  getFormattedDate(curDateTime, "YYYY MMM dd");
  
  getFormattedDate(curDateTime, "MMMM dd yyyy hh:mm a");
 }

 
 /**
  * 
  * @param dt
  * @param pattern
  * @return
  */
 private static void getFormattedDate(LocalDateTime dt, String pattern){
  DateTimeFormatter df = DateTimeFormatter.ofPattern(pattern);
  System.out.println("Formatted date " + " For Pattern " + pattern + " is "+ dt.format(df));
 }

}

Output

Date before formatting 2017-08-13T20:20:07.979
Formatted date  For Pattern dd/MM/yyyy is 13/08/2017
Formatted date  For Pattern YYYY MMM dd is 2017 Aug 13
Formatted date  For Pattern MMMM dd yyyy hh:mm a is August 13 2017 08:20 PM

That's all for this topic How to convert Date to String in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. How to convert String to Date in Java
  2. How to format date in Java using SimpleDateFormat
  3. How to find last modified date of a file in Java

You may also like -

>>>Go to Java Programs page

Thursday, 10 August 2017

How to create immutable class in Java

Immutable class, as the name suggests, is a class whose object can’t be modified in anyway once created. Once an object of the immutable class is created and initialized the content of any field of that object can’t be changed in anyway and remains same throughout the life of the object. If there are methods that should modify the content in some way then a new object is created with the modified content and returned, original object does not change.

As example String in Java is an immutable class though there are methods with in String class like substring or replace which modify the created String object. You can see in the code of the String class that for all these type of methods a new string is created with the modified data and returned. Other examples of immutable classes in Java are all the wrapper classes for primitive types like Integer, Long etc. BigDecimal and BigInteger are also immutable classes.

How to create an immutable class

There are certain steps that are to be followed for creating an immutable class –

  1. Methods of the class should not be overridden by the subclasses. You can ensure that by making your class final.

  2. Make all fields final and private. If the field is of primitive type, then it’s value can’t be changed as it is final. If field is holding a reference to another object, then declaring that field as final means its reference can’t be changed.
    Having access modifier as private for the fields ensure that fields are not accessed outside the class.

  3. Initialize all the fields in a constructor.

  4. Don’t provide setter methods or any method that can change the state of the object. Only provide methods that can access the value (like getters).

  5. In case any of the fields of the class holds reference to a mutable object any change to those objects should also not be allowed, for that –
    • Make sure that there are no methods with in the class that can change those mutable objects (change any of the field content).
    • Don’t share reference of the mutable object, if any of the methods of your class return the reference of the mutable object then its content can be changed.
    • If reference must be returned create copies of your internal mutable objects and return those copies rather than the original object. The copy you are creating of the internal mutable object must be a deep copy not a shallow copy.

In case you are wondering why such elaborate procedure for the fields holding references when fields are already final and references can’t be changed. Remember that even if reference cannot be changed you can still change the content of the fields with in a mutable object which goes against what you want to achieve by making your class immutable.

Example Code

In the example there are two classes. Address class is the mutable class whose object is there in the immutable class ImmutableEmployee.

Address.java

public class Address {
 private String addressLine1;
 private String addressLine2;
 private String city;
 public String getAddressLine1() {
  return addressLine1;
 }
 public void setAddressLine1(String addressLine1) {
  this.addressLine1 = addressLine1;
 }
 public String getAddressLine2() {
  return addressLine2;
 }
 public void setAddressLine2(String addressLine2) {
  this.addressLine2 = addressLine2;
 }
 public String getCity() {
  return city;
 }
 public void setCity(String city) {
  this.city = city;
 }
 public String toString() {
  return "AddressLine1 " + addressLine1 + " AddressLine2 " + addressLine2 + " City " + city;
 }
}

ImmutableEmployee

public class ImmutableEmployee {
 private final String name;
 private final int age;
 private final Address empAddress;
 ImmutableEmployee(String name, int age, String add1, String add2, String city){
  this.name = name;
  this.age = age;
  // don't pass reference around create a new object with in constructor
  empAddress = new Address();
  empAddress.setAddressLine1(add1);
  empAddress.setAddressLine2(add2);
  empAddress.setCity(city);
 }
 
 public String getName() {
  return name;
 }
 public int getAge() {
  return age;
 }
 
 public Address getEmpAddress() {
  Address adr = new Address();
  adr.setAddressLine1(empAddress.getAddressLine1());
  adr.setAddressLine2(empAddress.getAddressLine2());
  adr.setCity(empAddress.getCity());
  return adr;
  /*return empAddress;*/
 }
 
 public String toString() {
  return "Name " + name + " Age " + age + " Address " + empAddress;
 }

 public static void main(String[] args) {
  ImmutableEmployee ie = new ImmutableEmployee("Jack", 32, "34, Hunter's Glen", "Pine Street", "Brooklyn");
  System.out.println("Employee information " + ie);
  Address adr = ie.getEmpAddress();
  adr.setCity("London");
  System.out.println("Employee information " + ie);
 }

}

Output

Employee information Name Jack Age 32 Address AddressLine1 34, Hunter's Glen AddressLine2 Pine Street City Brooklyn
Employee information Name Jack Age 32 Address AddressLine1 34, Hunter's Glen AddressLine2 Pine Street City Brooklyn

Here notice that in the line Address adr = ie.getEmpAddress(); I get the address object and change the city in the object but that change is not reflected in the Employee object because getEmpAddress() method creates and returns a new Address object.

You can change that method to return the original Address object, in that case your getEmpAddress() method will look like this –

 public Address getEmpAddress() {
  /*Address adr = new Address();
  adr.setAddressLine1(empAddress.getAddressLine1());
  adr.setAddressLine2(empAddress.getAddressLine2());
  adr.setCity(empAddress.getCity());
  return adr;*/
  return empAddress;
 }

Now if you execute the code and see the output -

Output

Employee information Name Jack Age 32 Address AddressLine1 34, Hunter's Glen AddressLine2 Pine Street City Brooklyn
Employee information Name Jack Age 32 Address AddressLine1 34, Hunter's Glen AddressLine2 Pine Street City London

You can see that Employee information is changed, you are now able to change the content of the Employee class object which should not be happening as it’s an immutable class. That’s why the point as mentioned above “If reference must be returned create copies of your internal mutable objects and return those copies rather than the original object.” is important.

If your class has any mutable object or using any of the modifiable collections like ArrayList, HashSet, HashMap same steps are to be followed.

Advantages of using immutable class

  1. One of the advantage of an immutable class is it is thread safe and its object can be shared among many threads without any fear of content of the original object getting changed. Refer String and thread safety to have more clarity on this point.

  2. Another advantage is you can cache immutable class objects as you know content won’t change once the object is created so no fear of dirty read. This ability to cache and reuse reduces overhead.

  3. If you ever wondered why do you see mostly String as a key for HashMap, yes, it is mostly because of String being immutable. So, if you are somehow required to use your own custom object as key and want to make sure that the object is not changed by any means (like any other thread) making that class immutable will be an option.

Disadvantages of using immutable class

  1. If the second point in the advantages of using immutable class has impressed you to make as many immutable classes as possible just take a pause and think of the disadvantage too. Any get method where you are supposed to return the immutable class object or any field that holds a reference to a mutable object you do need to create a new object every time, copy the content from the original object and then return it. Which results in creation of many new objects and performing deep copies which again is expensive.

That's all for this topic How to create an immutable class in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. How to create deadlock in Java multi-threading - Java Program
  2. Print odd-even numbers using threads and wait-notify
  3. How to remove duplicate elements from an array - Java Program
  4. String and thread-safety in Java
  5. String comparison in Java

You may also like -

>>>Go to Java Basics page

Monday, 7 August 2017

Invoking getters and setters using Reflection - Java Program

In the post reflection in java – method it is already explained how you can invoke a method of the class at runtime even a private method.

In this post we’ll use that knowledge to invoke getters and setters of the class using reflection. Here two ways of doing that are discussed -

  • Using the PropertyDescriptor class.
  • Scanning methods of the class and look for set and get methods.

Using PropertyDescriptor class

A PropertyDescriptor describes one property that a Java Bean exports via a pair of accessor methods. Then using the getReadMethod() and getWriteMethod() you can call the setter and getter for the property.

Example Code

Here in the example we have a class TestClass which has getter and setter for three fields which are of type int, String and boolean. Then in the GetterAndSetter class there are methods to invoke the getters and setters of the given class.

TestClass.java

package org.prgm;

public class TestClass {
 private int value;
 private String name;
 private boolean flag;
 public int getValue() {
  return value;
 }
 public void setValue(int value) {
  this.value = value;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public boolean isFlag() {
  return flag;
 }
 public void setFlag(boolean flag) {
  this.flag = flag;
 }
}

GetterAndSetter.java

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

public class GetterAndSetter {
 public static void main(String[] args) {
  GetterAndSetter gs = new GetterAndSetter();
  TestClass tc = new TestClass();
  gs.callSetter(tc, "name", "John");
  gs.callSetter(tc, "value", 12);
  gs.callSetter(tc, "flag", true);
  // Getting fields of the class
  Field[] fields = tc.getClass().getDeclaredFields();
  
  for(Field f : fields){
   String fieldName = f.getName();
   System.out.println("Field Name -- " + fieldName);
   
   
  }
  gs.callGetter(tc, "name");
  gs.callGetter(tc, "value");
  gs.callGetter(tc, "flag");
 }
 
 /**
  * 
  * @param obj
  * @param fieldName
  * @param value
  */
 private void callSetter(Object obj, String fieldName, Object value){
  PropertyDescriptor pd;
  try {
   pd = new PropertyDescriptor(fieldName, obj.getClass());
   pd.getWriteMethod().invoke(obj, value);
  } catch (IntrospectionException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
 
 /**
  * 
  * @param obj
  * @param fieldName
  * @param value
  */
 private void callGetter(Object obj, String fieldName){
  PropertyDescriptor pd;
  try {
   pd = new PropertyDescriptor(fieldName, obj.getClass());
   System.out.println("" + pd.getReadMethod().invoke(obj));
  } catch (IntrospectionException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
}

Output

Field Name -- value
Field Name -- name
Field Name -- flag
John
12
true

Scanning methods of the class and look for set and get methods

Another way to invoke the getters and setters is to scan all the methods of the class through reflection and then find out which are the getters and setters method.

It is particularly useful to use this way to call get methods if you have lots of fields in a class. Calling set method that way won’t be of much help as you will have to still invoke individual method with the value that has to be set.

Logic to identify get method

get method starts with get or is (in case of boolean), it should not have any parameters and it should return a value.

Logic to identify set method

set method starts with set and it should have a parameter and it shouldn't return any value which means it should return void.

Example Code

Same Java bean class as above TestClass is used here too.

GetterAndSetter.java

In the GetterAndSetter class there are methods to identify the getters and setters of the given class. If it is a get method that is invoked to get the value. For set method name of the method is printed.

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class GetterAndSetter {
    public static void main(String[] args) {
        TestClass tc = new TestClass();
        // Setting values
        tc.setName("John");
        tc.setValue(12);
        tc.setFlag(true);
        
        Method[] methods = tc.getClass().getDeclaredMethods();
        for(Method method : methods){
            if(isGetter(method)){
                try {
                    Object obj = method.invoke(tc);
                    System.out.println("Invoking "+ method.getName() + " Returned Value - " + obj);
                } catch (IllegalAccessException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(isSetter(method)){
                System.out.println("Setter -- " + method.getName());
            }
        }
    }
    
    /**
     * 
     * @param method
     * @return
     */
    private static boolean isGetter(Method method){
        // identify get methods
        if((method.getName().startsWith("get") || method.getName().startsWith("is")) 
                && method.getParameterCount() == 0 && !method.getReturnType().equals(void.class)){
            return true;
        }
        return false;    
    }
    
    /**
     * 
     * @param method
     * @return
     */
    private static boolean isSetter(Method method){
        // identify set methods
        if(method.getName().startsWith("set") && method.getParameterCount() == 1 
                && method.getReturnType().equals(void.class)){
            return true;
        }
        return false;    
    }
}

Output

Invoking getName Returned Value - John
Invoking getValue Returned Value - 12
Setter -- setName
Setter -- setValue
Setter -- setFlag
Invoking isFlag Returned Value - true

That's all for this topic Invoking getters and setters using Reflection - Java Program. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Generating getters and setters using Reflection - Java Program
  2. Reflection in Java
  3. Reflection in Java - Class
  4. Reflection in Java - Constructor
  5. Reflection in Java - Field

You may also like -

>>>Go to Java advance topics page

Friday, 4 August 2017

Reflection in Java - Method

Reflection in Java class gives a good idea about how class is an entry point to all the Reflection APIs. Once you have Class object you can get information about members of the class like fields, constructors, methods.

Member Interface

With in the Reflection hierarchy an interface java.lang.reflect.Member is defined which is implemented by java.lang.reflect.Field, java.lang.reflect.Method, and java.lang.reflect.Constructor. Thus Member is an interface that reflects identifying information about a single member (a field or a method) or a constructor.

This post talks about Method class and the methods it provides in detail. Class methods have return values, parameters, and may throw exceptions. The java.lang.reflect.Method class provides methods for obtaining the type information for the parameters and return value. It may also be used to invoke methods on a given object.

How to get Method object

Once you have instance of the Class you can use any of the following 4 methods for getting information about methods of the class.

  • getMethod(String name, Class<?>... parameterTypes) - Returns a Method object that reflects the specified public member method of the class or interface represented by this Class object.
  • getMethods() - Returns an array containing Method objects reflecting all the public methods of the class or interface represented by this Class object, including those declared by the class or interface and those inherited from superclasses and superinterfaces.
  • getDeclaredMethod(String name, Class<?>... parameterTypes) - Returns a Method object that reflects the specified declared method of the class or interface represented by this Class object.
  • getDeclaredMethods() - Returns an array containing Method objects reflecting all the declared methods of the class or interface represented by this Class object, including public, protected, default (package) access, and private methods, but excluding inherited methods.

Example code

As a preparation for the example code let’s have a class called Parent.java which will be extended by the class ChildClass.java which is the class we are going to examine. There is also an interface IntTest.java which is implemented by ChildClass.java.

Parent class

public class Parent {
 String name;
 Parent(String name){
  this.name = name;
 }

 public void displayName(String name){
  System.out.println("Hello - " + name);
 }
  
 public String getName(){
  return name;
 }
}

IntTest interface

public interface IntTest {
 public void showValue();
}

ChildClass.java

public class ChildClass extends Parent implements IntTest{
 private int value;
 //Constructor
 public ChildClass(String name, int value) {
  super(name);
  this.value = value;
 }

 @Override
 public void showValue() {
  System.out.println("Value - " + value);  
 }
}

Now let’s see how you can get method information using all the four methods mentioned above.

import java.lang.reflect.Method;
import java.util.Arrays;

public class ReflectMethod {
    public static void main(String[] args) {
        try {
            // Getting Class instance
            Class<?> c = Class.forName("org.netjs.prog.ChildClass");
            
            // Using getMethod(methodName, parameters)
            Method method = c.getMethod("displayName", String.class);
            System.out.println("Method params " + Arrays.toString(method.getParameters()));
            
            // Will throw exception
            /*method = c.getDeclaredMethod("displayName", String.class);
            System.out.println("Method params " + Arrays.toString(method.getParameters()));*/
            
            Method[] methodArr = c.getMethods();
            System.out.println("All methods " + Arrays.toString(methodArr));
            
            methodArr = c.getDeclaredMethods();
            System.out.println("Class methods " + Arrays.toString(methodArr));
            
        } catch (ClassNotFoundException | NoSuchMethodException | SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

Output

Method params [java.lang.String arg0]

All methods [public void org.netjs.prog.ChildClass.showValue(), public java.lang.String org.netjs.prog.Parent.getName(), 
public void org.netjs.prog.Parent.displayName(java.lang.String), 
public final void java.lang.Object.wait() throws java.lang.InterruptedException, 
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException, 
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException, 
public boolean java.lang.Object.equals(java.lang.Object), public java.lang.String java.lang.Object.toString(), 
public native int java.lang.Object.hashCode(), public final native java.lang.Class java.lang.Object.getClass(), 
public final native void java.lang.Object.notify(), public final native void java.lang.Object.notifyAll()]

Class methods [public void org.netjs.prog.ChildClass.showValue()]

First call to the getMethod with parameters method name and parameter types returns the matching method. Then parameters of the method are printed using the getParameters() method of the Method class.

Second call (Which is commented) will throw NoSuchMethodException as the method displayName is inherited from the parent class and getDeclaredMethod() will work for the methods with in the class.

getMethods() will return all the methods of the class and also the inherited methods.

GetDeclaredMethods() will return all the methods of the class but not the inherited one.

Getting method parameter types and return type

If we have a class called ChildClass as follows then we can get its method parameter types and return type using reflection.

ChildClass.java

public class ChildClass extends Parent implements IntTest{
 private int value;
 //Constructor
 public ChildClass(String name, int value) {
  super(name);
  this.value = value;
 }

 @Override
 public void showValue() {
  System.out.println("Value - " + value);  
 }
 
 public String getValue(String name) throws Exception{
  return "Hello" + name;
 }

}

Example code

// Getting Class instance
Class<?> c = Class.forName("org.netjs.prog.ChildClass");
methodArr = c.getDeclaredMethods();
for(Method m: methodArr){
    System.out.println("For Method - " + m.getName() + " Parameter types are - " + Arrays.toString(m.getParameterTypes()));
    System.out.println("For Method - " + m.getName() + " Return type " + m.getReturnType());
}

Output

For Method - getValue Parameter types are - [class java.lang.String]
For Method - getValue Return type class java.lang.String
For Method - showValue Parameter types are - []
For Method - showValue Return type void

Getting method modifiers

If you want to get information about the modifiers of the methods of the class you can use getModifiers() method whose return type is int.

Example code

// Getting Class instance
Class<?> c = Class.forName("org.netjs.prog.ChildClass");
methodArr = c.getDeclaredMethods();
for(Method m: methodArr){
    System.out.println("For Method - " + m.getName() + 
 " modifier is - " + Modifier.toString(m.getModifiers()));
}

Output

For Method - getValue modifier is – public
For Method - showValue modifier is – public

Getting thrown exceptions

If you want to get information about types of exceptions declared to be thrown by the methods of the class you can use getExceptionTypes() method.

Example code

// Getting Class instance
Class<?> c = Class.forName("org.netjs.prog.ChildClass");
methodArr = c.getDeclaredMethods();
for(Method m: methodArr){
    System.out.println("For Method - " + m.getName() + " Thrown Exceptions  - " 
 + Arrays.toString(m.getExceptionTypes()));
}

Output

For Method - getValue Thrown Exceptions  - [class java.lang.Exception]
For Method - showValue Thrown Exceptions  - []

Invoking method using reflection

Using refelction you can also invoke methods on a class. Methods are invoked using java.lang.reflect.Method.invoke() method. The first argument is the object instance on which this particular method is to be invoked. (If the method is static, the first argument should be null.) Subsequent arguments are the method's parameters.

Example code

// Getting Class instance
Class<?> c = Class.forName("org.netjs.prog.ChildClass");
// Getting class object
ChildClass ch = new ChildClass("Test", 10);
Method method = c.getDeclaredMethod("getValue", String.class);
try {
    String result = (String)method.invoke(ch, "Reflection");
    System.out.println("Method invocation returned - " + result);
} catch (IllegalAccessException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IllegalArgumentException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (InvocationTargetException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

Output

Method invocation returned – HelloReflection

Invoking private method of the class

You can even invoke the private method of the class using reflection. Using getDeclaredMethod() you can get even the private method of the class.

Once you have the method object you can use the setAccessible() method which is inherited from class java.lang.reflect.AccessibleObject to set the access for the private method as true at run time and then invoke it from another class.

Let’s say we have a ChildClass as follows with a private method getValue().

public class ChildClass extends Parent implements IntTest{
 private int value;
 //Constructor
 public ChildClass(String name, int value) {
  super(name);
  this.value = value;
 }

 @Override
 public void showValue() {
  System.out.println("Value - " + value);  
 }
 
      private String getValue(String name) throws Exception{
  return "Hello" + name;
 }
}

Now you want to invoke this private method.

Example code

// Getting Class instance
Class<?> c = Class.forName("org.netjs.prog.ChildClass");
// Getting class object
ChildClass ch = new ChildClass("Test", 10);
Method method = c.getDeclaredMethod("getValue", String.class);
method.setAccessible(true);
try {
    String result = (String)method.invoke(ch, "Reflection");
    System.out.println("Method invocation returned - " + result);
} catch (IllegalAccessException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IllegalArgumentException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (InvocationTargetException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

Output

Method invocation returned – HelloReflection

You can comment the line where access to the method is set as true.

//method.setAccessible(true);

Then if you execute it you will get the exception as follows -

java.lang.IllegalAccessException: Class org.netjs.prog.ReflectMethod can not access a member of class 
org.netjs.prog.ChildClass with modifiers "private"
 at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)
 at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(Unknown Source)
 at java.lang.reflect.AccessibleObject.checkAccess(Unknown Source)
 at java.lang.reflect.Method.invoke(Unknown Source)
 at org.netjs.prog.ReflectMethod.main(ReflectMethod.java:32)

That's all for this topic Reflection in Java - Method. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Reflection in Java
  2. Reflection in Java - Field
  3. Reflection in Java - Method
  4. Reflection in Java - Constructor
  5. Generating getters and setters using Reflection - Java Program

You may also like -

>>>Go to Java advance topics page

Generating getters and setters using Reflection - Java Program

When you right click in any Java Bean class with in the eclipse IDE and click on Source – Generate Getters and Setters you get the getter and setter methods for the selected fields. Ever wondered what goes in the background to generate the getter and setter methods?

Yes, it is the magic of reflection in Java which gets the information about the fields of the class and their types and then generate the getters and setters accordingly.

If you have to create such a class yourself then using the refelction API you can create your own getters and setters generator class, of course just for academic purpose, as all the IDEs anyway provide the facility to do that.

Example code

Let’s say you have a class TestClass with three fields of type int, String and Boolean and you want to generate getters and setters for these 3 fields.

TestClass

public class TestClass {

 private int value;
 private String name;
 private boolean flag;
} 

GetterSetterGenerator class

Using the reflection API for the field you can get information about the fields of the given class – like name and type. Once you have that information you can create set and get methods for the fields. In this code set and get methods are just printed after creating them as it is just for illustrating the usage of reflection in Java so not going into File I/O.

import java.lang.reflect.Field;
import java.util.Arrays;

public class GetterSetterGenerator {

 public static void main(String[] args) {
  try {
   GetterSetterGenerator gt = new GetterSetterGenerator();
   StringBuffer sb = new StringBuffer();
   
   Class<?> c = Class.forName("org.prgm.TestClass");
   // Getting fields of the class
   Field[] fields = c.getDeclaredFields();
   System.out.println("Fields - " + Arrays.toString(fields));
   for(Field f : fields){
    String fieldName = f.getName();
    String fieldType = f.getType().getSimpleName();
    
    System.out.println("Field Name -- " + fieldName);
    System.out.println("Field Type " + fieldType);
    
    gt.createSetter(fieldName, fieldType, sb);
    
    gt.createGetter(fieldName, fieldType, sb);
   }
   System.out.println("" + sb.toString());
   
  }catch (ClassNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }  


 }
 /**
  * 
  * @param fieldName
  * @param fieldType
  * @param setter
  */
 private void createSetter(String fieldName, String fieldType, StringBuffer setter){
  
  setter.append("public void").append(" set");
  setter.append(getFieldName(fieldName));
  setter.append("(" + fieldType + " " + fieldName + ") {");
  setter.append("\n\t this."+ fieldName + " = " + fieldName + ";");
  setter.append("\n" + "}" + "\n");
 }
 
 /**
  * 
  * @param fieldName
  * @param fieldType
  * @param setter
  */
 private void createGetter(String fieldName, String fieldType, StringBuffer getter){
  getter.append("public " + fieldType).append((fieldType.equals("boolean")?" is" : " get") + getFieldName(fieldName) + "(){");
  getter.append("\n\treturn " + fieldName + ";");
  getter.append("\n" + "}" + "\n");
 }
 
 /**
  * 
  * @param fieldName
  * @return
  */
 private String getFieldName(String fieldName){
  return fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1, fieldName.length());
 }
}

Output

 Fields - [private int org.prgm.TestClass.value, private java.lang.String org.prgm.TestClass.name, private boolean org.prgm.TestClass.flag]
Field Name -- value
Field Type int
Field Name -- name
Field Type String
Field Name -- flag
Field Type Boolean

public void setValue(int value) {
  this.value = value;
}
public int getValue(){
 return value;
}
public void setName(String name) {
  this.name = name;
}
public String getName(){
 return name;
}
public void setFlag(boolean flag) {
  this.flag = flag;
}
public boolean isFlag(){
 return flag;
}

That's all for this topic Generating getters and setters using Reflection - Java Program. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Invoking getters and setters using Reflection - Java Program
  2. Reflection in Java - Class
  3. Reflection in Java - Method
  4. Reflection in Java - Constructor
  5. Reflection in Java

You may also like -

>>>Go to Java advance topics page

Monday, 31 July 2017

Reflection in Java - Array

Array in Java is also a class so many of the methods in java.lang.Class may be used with the array.

Reflection in Java also provides a specific class java.lang.reflect.Array for arrays.

How to identify array

If you want to determine if a class member is a field of array type that can be done by invoking Class.isArray() method.

Example code

For the example let’s say we have a class TestClass which has one array field numArray. In another class ReflectArray using the class.isArray() method it is determined if there is any array in the TestClass.

TestClass

public class TestClass {
 private int value;
 private int[] numArray;
 public int getValue() {
  return value;
 }
 public void setValue(int value) {
  this.value = value;
 }
 public int[] getNumArray() {
  return numArray;
 }
 public void setNumArray(int[] numArray) {
  this.numArray = numArray;
 }
}

ReflectArray

import java.lang.reflect.Field;

public class ReflectArray {

    public static void main(String[] args) {
        try {
            Class<?> c = Class.forName("org.netjs.prog.TestClass");
            Field[] fields = c.getDeclaredFields();
            for (Field f : fields) {
                Class<?> type = f.getType();
                // Looking for array
                if(type.isArray()){
                    System.out.println("Array found " + f.getName());
                }
            }
            
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

Output

Array found numArray

Creating new array refelctively

Using reflection you can dynamically create arrays of arbitrary type and dimensions using java.lang.reflect.Array.newInstance() method.

Example code

int[] testArray = (int[])Array.newInstance(int.class, 5);
System.out.println("length of array " + testArray.length);

Output

length of array 5

Getting and setting array

Using reflection you can get or set an entire array. You can set an entire array using Field.set(Object obj, Object value) method. To retrieve an entire array use

Field.get(Object obj)

method.

If you want to get or set an array individual element by element, Array class has methods for that also. In order to set or get an int array you can use setInt(Object array, int index, int i) and getInt(Object array, int index) methods. Same way if you have a float array you can use setFloat(Object array, int index, float f) and getFloat(Object array, int index) methods.

There is also a method which takes Object for value as parameter that can be used with any type - set(Object array, int index, Object value) and get(Object array, int index) methods.

Example code

int[] testArray = (int[])Array.newInstance(int.class, 5);
System.out.println("length of array " + testArray.length);
// Setting values using setInt and set methods
Array.setInt(testArray, 0, 1);
Array.set(testArray, 1, 2);
Array.setInt(testArray, 2, 3);

// Getting values using getInt and get methods
System.out.println("First element " + Array.get(testArray, 0));
System.out.println("Second element " + Array.getInt(testArray, 1));
System.out.println("Third element " + Array.getInt(testArray, 2));

Output

length of array 5
First element 1
Second element 2
Third element 3

That's all for this topic Reflection in Java - Array. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Reflection in Java - Field
  2. Reflection in Java - Method
  3. Reflection in Java - Constructor
  4. Generating getters and setters using Reflection - Java Program
  5. Invoking getters and setters using Reflection - Java Program

You may also like -

>>>Go to Java advance topics page

Wednesday, 26 July 2017

Reflection in Java - Constructor

Similar to reflection API for methods, there is also reflection API to get information about the constructors of a class. Using java.lang.reflect.Constructor you can get information about the modifiers, parameters, annotations, and thrown exceptions. You can also create a new instance of a class using a specified constructor.

How to get Constructor object

As always the starting point is the Class and there are four methods provided by the class Class for getting the constructors.
  • getConstructor(Class<?>... parameterTypes) - Returns a Constructor object that reflects the specified public constructor of the class represented by this Class object. The parameterTypes parameter is an array of Class objects that identify the constructor's formal parameter types, in declared order.
  • getConstructors() - Returns an array containing Constructor objects reflecting all the public constructors of the class represented by this Class object.
  • getDeclaredConstructor(Class<?>... parameterTypes) – Returns a Constructor object that reflects the specified constructor of the class or interface represented by this Class object. The parameterTypes parameter is an array of Class objects that identify the constructor's formal parameter types, in declared order.
  • getDeclaredConstructors() - Returns an array of Constructor objects reflecting all the constructors declared by the class represented by this Class object. These are public, protected, default (package) access, and private constructors.

Example code

For example we’ll be using this class TestClass which has one public constructor with 2 args and a private constructor.

TestClass.java

public class TestClass {
 private int value;
 private String name;
 // public Constructor
 public TestClass(int value, String name) {
  
  this.value = value;
 }
 // private constructor
 private TestClass() {
  
 }
 
 public void showValue() {
  System.out.println("Value - " + value);
  
 }
 
}

If you want to get constructors using the above 4 methods it can be done as follows –

import java.lang.reflect.Constructor;
import java.util.Arrays;

public class ReflectConstructor {

 public static void main(String[] args) {
  try {
   Class<?> c = Class.forName("org.prgm.TestClass");
   // To get constructor with 2 args
   Constructor<?> constructor = c.getConstructor(int.class, String.class);
   //Constructor<?> constructor = c.getConstructor(new Class[]{int.class, String.class});
   
   System.out.println("constructor " + constructor.toString());
   // to get private constructor using getDeclaredConstructor() method
   constructor = c.getDeclaredConstructor();
   System.out.println("constructor " + constructor.toString());
   
   // Getting constructors of the class
   Constructor<?>[] constructors = c.getConstructors();
   System.out.println("Constructors - " + Arrays.toString(constructors));
   
   Constructor<?>[] Decconstructors = c.getDeclaredConstructors();
   System.out.println("Declared constructors - " + Arrays.toString(Decconstructors));
  } catch (ClassNotFoundException | NoSuchMethodException | SecurityException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

 }

}

Output

constructor public org.prgm.TestClass(int,java.lang.String)
constructor private org.prgm.TestClass()
Constructors - [public org.prgm.TestClass(int,java.lang.String)]
Declared constructors - [public org.prgm.TestClass(int,java.lang.String), private org.prgm.TestClass()]

Here note that in the first call two parameters are passed with the getConstructor() method which match the arguments of the constructor in the TestClass class. Since parameter is defined as varargs in getConstructor() so you can pass as comma separated parameters or as an array of class objects. Which is done as an illustration in the commented code.

Second call uses the getDeclaredConstructor(); method as that can return constructor object pertaining to private constructor too.

Same way getDeclaredConstructors() method returns an array of Constructor objects reflecting all the constructors of the class public or private where as getConstructors() method returns an array of constructor objects reflecting all the public constructors of the class.

Example code

Class<?> c = Class.forName("org.prgm.TestClass");
Constructor<?>[] Decconstructors = c.getDeclaredConstructors();
for(Constructor<?> ctr : Decconstructors){
 System.out.println("Constructor -- " + ctr.getName());
 Class<?>[] pType  = ctr.getParameterTypes();
 for (int i = 0; i < pType.length; i++) {
  System.out.println("Parameter -- " + pType[i]);
 }
}

Getting modifiers of the constructors

You can get modifiers of the constructors of the class through reflection using getModifiers() method.

Example code

Class<?> c = Class.forName("org.prgm.TestClass");
Constructor<?>[] Decconstructors = c.getDeclaredConstructors();
for(Constructor<?> ctr : Decconstructors){
 System.out.println("Constructor -- " + ctr.getName() + " has modifier " 
  +  Modifier.toString(ctr.getModifiers()));
}

Output

Constructor -- org.prgm.TestClass has modifier public
Constructor -- org.prgm.TestClass has modifier private

Creating class instance

In reflection API there are two methods for creating instances of classes - java.lang.reflect.Constructor.newInstance() and Class.newInstance(). It is preferable to go with the one provided by the Constructor class for the reasons explained here -

  1. Class.newInstance() can only invoke the zero-argument constructor, while Constructor.newInstance() may invoke any constructor, regardless of the number of parameters.
  2. Class.newInstance() requires that the constructor be visible; Constructor.newInstance() can invoke private constructors also by setting accessibility to true.
  3. Class.newInstance() throws any exception thrown by the constructor whether it is checked or unchecked exception. Constructor.newInstance() always wraps the thrown exception with an InvocationTargetException.

Example code

For the TestClass.java which has one public constructor with two arguments and one no-arg private constructor, creating new class instances can be done as follows.

Class<?> c = Class.forName("org.prgm.TestClass");
Constructor<?>[] Decconstructors = c.getDeclaredConstructors();
for(Constructor<?> ctr : Decconstructors){
 System.out.println("Constructor -- " + ctr.getName());
 try {
  TestClass t;
  if(Modifier.toString(ctr.getModifiers()).equals("private")){
   // Setting accessibility to true if it's a private constructor
   ctr.setAccessible(true);
   t = (TestClass)ctr.newInstance();
  }else{
   t = (TestClass)ctr.newInstance(100, "InstanceTest");
  }   
  t.showValue();
    
 } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
   e.printStackTrace();
 }   
}

Output

Constructor -- org.prgm.TestClass
Value - 100
Constructor -- org.prgm.TestClass
Value – 0

In the code there is a check for the modifier of the constructor. If it is private then the set the accessible flag to true, with that even private constructor can be accessed from another class and an instance created.

That's all for this topic Reflection in Java - Constructor. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Reflection in Java - Class
  2. Reflection in Java - Field
  3. Serialization in Java

You may also like -

>>>Go to Java advance topics page

Wednesday, 19 July 2017

Reflection in Java - Field

Reflection in Java class gives a good idea about how class is an entry point to all the Reflection APIs. Once you have Class object you can get information about members of the class fields, constructors, methods.

Member Interface

With in the Reflection hierarchy an interface java.lang.reflect.Member is defined which is implemented by java.lang.reflect.Field, java.lang.reflect.Method, and java.lang.reflect.Constructor. Thus Member is an interface that reflects identifying information about a single member (a field or a method) or a constructor.

This post talks about Field class and the methods it provides in detail. Class fields have a type and a value, the java.lang.reflect.Field class provides methods for accessing type information, field’s modifier and setting and getting values of a field on a given object.

How to get Field object

There are 4 methods for getting fields of the class.

  • getField(String name) - Returns a Field object that reflects the specified public member field of the class or interface represented by this Class object.
  • getFields() - Returns an array containing Field objects reflecting all the accessible public fields of the class or interface represented by this Class object.
  • getDeclaredField(String name) - Returns a Field object that reflects the specified declared field of the class or interface represented by this Class object.
  • getDeclaredFields() - Returns an array of Field objects reflecting all the fields declared by the class or interface represented by this Class object.

So getFields() methods will only return object for public fields where as getDeclaredField() methods will return all the fields.

Example code

In this example generic class ReflectField is used which has few fields with access modifier as public or private.

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;

public class ReflectField<T> {
     public String name = "Test";
     private int i = 10;
     public List<Integer> numList;
     public T val;
     
     public static void main(String arg[]){
      try {
       Class<?> c = Class.forName("org.netjs.prog.ReflectField");
       try {
        Field f = c.getField("name");
        System.out.println("Name field " + f.getName());
        
        Field[] fields = c.getFields();
        System.out.println("All Fields - " + Arrays.toString(fields));
        
        fields = c.getDeclaredFields();
        
        System.out.println("Declared Fields - " + Arrays.toString(fields));
       } catch (NoSuchFieldException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
       } catch (SecurityException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
       }
       
      }catch (ClassNotFoundException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
      }
    }
}

Output

Name field name

All Fields - [public java.lang.String org.netjs.prog.ReflectField.name, public java.util.List org.netjs.prog.ReflectField.numList, 
public java.lang.Object org.netjs.prog.ReflectField.val]

Declared Fields - [public java.lang.String org.netjs.prog.ReflectField.name, private int org.netjs.prog.ReflectField.i, 
public java.util.List org.netjs.prog.ReflectField.numList, public java.lang.Object org.netjs.prog.ReflectField.val]

You can see here getFields() return array of all public fields in the class where as getDeclaredFields() return all the fields (field i is having access modifier as private).

Getting the field type

If you want to know the types of fields in any class reflectively you can do it using the methods getType() and getGenericType() methods.

Example code

Class<?> c = Class.forName("org.netjs.prog.ReflectField");
fields = c.getDeclaredFields();
for(Field field : fields){
    System.out.println("Field name - " + field.getName() + " has Field Type " + field.getType());
    System.out.println("Field name - " + field.getName() + " has Generic Field Type " + field.getGenericType());
}

Output

Field name - name has Field Type class java.lang.String
Field name - name has Generic Field Type class java.lang.String
Field name - i has Field Type int
Field name - i has Generic Field Type int
Field name - numList has Field Type interface java.util.List
Field name - numList has Generic Field Type java.util.List<java.lang.Integer>
Field name - val has Field Type class java.lang.Object
Field name - val has Generic Field Type T

Here notice that the type for the field val is displayed as java.lang.Object because generics are implemented via type erasure which removes all information regarding generic types during compilation. Thus T is replaced by the upper bound of the type variable, in this case, java.lang.Object.

Getting field modifiers

You can get the field modifiers by using the getModifiers() method. This method returns the Java language modifiers for the field represented by this Field object, as an integer. The Modifier class should be used to decode the modifiers.

Example code

Class<?> c = Class.forName("org.netjs.prog.ReflectField");
fields = c.getDeclaredFields();
for(Field field : fields){     
    System.out.println("Field name - " + field.getName() + " has modifier " + Modifier.toString(field.getModifiers()));
}

Output

Field name - name has modifier public
Field name - i has modifier private
Field name - numList has modifier public
Field name - val has modifier public

Getting and Setting Field Values

If you have an object of a class, using reflection you can set the values of fields in that class. This is typically done only in special circumstances when setting the values in the usual way is not possible. Because such access usually violates the design intentions of the class, it should be used with the utmost discretion.

Example code

Given a public field name which is of type String here the new value is set to the field name.

public String name = "Test";
Class<?> c = Class.forName("org.netjs.prog.ReflectField");
ReflectField rf = new ReflectField();
Field f = c.getField("name");
// getting the field value
System.out.println("Value of field name " + f.get(rf));
// setting the new field value
f.set(rf, "New Value");
System.out.println("Value of field name " + rf.name);

Output

Value of field name Test
Value of field name New Value

That's all for this topic Reflection in Java - Field. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Reflection in Java
  2. Reflection in Java - Class
  3. Invoking getters and setters using Reflection - Java Program
  4. Object cloning in java
  5. Serialization in Java

You may also like -

>>>Go to Java advance topics page

Monday, 17 July 2017

Reflection in Java - Class

For every type of object JVM creates an immutable instance of java.lang.Class which provides methods to examine the runtime properties of the object including its members and type information. Class also provides the ability to create new classes and objects.

With the exception of java.lang.reflect.ReflectPermission, none of the classes in java.lang.reflect have public constructors. To get to these classes, it is necessary to invoke appropriate methods on Class. So you can say that the entry point for all reflection operations is java.lang.Class.

How to get Class

There are several ways to get a Class depending on whether the code has access to an object, the name of class, a type, or an existing Class.

Object.getClass()

If you have an instance of the class available, then you can get Class by invoking Object.getClass() method. This method will only work with reference types.

For Example – If you have a class called ClassA and an object objA of that class then you can get instance of Class as follows –

ClassA objA = new ClassA();
Class<?> cls = objA.getClass();

Using .class Syntax

If instance of the class is not available but the type is known, then you can get object of Class by using .class syntax. You just need to add “.class” to the name of the type. Using .class you can also get the Class for a primitive type.

For Example – If you want class object for type Boolean.

boolean b;
Class cls = boolean.class;

Note here that type (Boolean) is used to get instance of Class.

Same way if you want Class object for ClassA.

ClassA objA;
Class<?> cls1 = ClassA.class;

Then if you want to instantiate class object objA you can do that using class.newInstance() method.

try {
 objA = (ClassA)cls1.newInstance();
 objA.setI(12);
 System.out.println("Value of i " + objA.getI());
} catch (InstantiationException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
} catch (IllegalAccessException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
}

Using Class.forName()

You can also get the instance of the class using the static method Class.forName().Make sure that you pass the fully-qualified class name. Which means you will have to include package names too.

For example – If you want instance of Class for ClassA which is residing in package org.prgm then do it as follows –

Class<?> c = Class.forName("org.prgm.ClassA");

Using TYPE Field for Primitive Type Wrappers

Wrapper classes for the primitive types have a field named TYPE which is equal to the Class for the primitive type being wrapped.

For example –

Class cls1 = Integer.TYPE;

Methods provided by class Class

There are many methods provided by the class Class to get the metadata about the class. Let’s go through an example to see some of these methods in practice.

Example code

As a preparation for the example code let’s have a class called Parent.java which will be extended by the class ChildClass.java which is the class we are going to examine. There is also an interface IntTest.java which is implemented by ChildClass.java.

Parent class

public class Parent {
 String name;
 Parent(String name){
  this.name = name;
 }

 public void displayName(){
  System.out.println("Hello - " + name);
 }
 
 public String getName(){
  return name;
 }
}

IntTest interface

public interface IntTest {
   public void showValue();
}

ChildClass.java

public class ChildClass extends Parent implements IntTest{
 private int value;
 //Constructor
 public ChildClass(String name, int value) {
  super(name);
  this.value = value;
 }

 @Override
 public void showValue() {
  System.out.println("Value - " + value);
  
 }
}

Based on these classes let us see some of the methods provided by class Class.

To get the class name

If you want to get the class name using the instance of the Class.

Class<?> c = Class.forName("org.prgm.ChildClass");
System.out.println("Class name " + c.getName());
System.out.println("Class name " + c.getSimpleName());

Output

Class name org.prgm.ChildClass
Class name ChildClass

As you can see using the method getName() gives you the fully qualified name whereas getSimpleName() method gives you only the class name.

Getting super class

getSuperClass() method can be used for getting Super class. Returns the Class representing the superclass of the entity represented by this Class. If this Class represents either the Object class, an interface, a primitive type, or void, then null is returned. If this object represents an array class then the Class object representing the Object class is returned.

Class<?> c = Class.forName("org.prgm.ChildClass");
System.out.println("Super Class name " + c.getSuperclass());

Output

Super Class name - class org.prgm.Parent

Getting implemented or extended interfaces

getInterfaces() method can be used for getting the interfaces. If the object on which you are calling this method represents a class, the return value is an array containing objects representing all interfaces implemented by the class. If this object represents an interface, the array contains objects representing all interfaces extended by the interface.

Class<?> c = Class.forName("org.prgm.ChildClass");
System.out.println("interfaces - " + Arrays.toString(c.getInterfaces()));

Output

interfaces - [interface org.prgm.IntTest]

Getting class modifier

You can get the class modifier by using the getModifiers() method. Returns the Java language modifiers for this class or interface, encoded in an integer. The modifiers consist of the Java Virtual Machine's constants for public, protected, private, final, static, abstract and interface; they should be decoded using the methods of class Modifier.

Class<?> c = Class.forName("org.prgm.ChildClass");
   
int modifiers = c.getModifiers();
System.out.println("Modifier - " + Modifier.toString(modifiers));

Output

Modifier – public

Getting fields of the class

There are 4 methods for getting fields of the class. If you want Field object for any specific field then you can use getDeclaredField(String name) or getField(String name) method. To get information for all the fields of the class you can following two methods.

  • getFields() - Returns an array containing Field objects reflecting all the accessible public fields of the class or interface represented by this Class object.
  • 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.
Class<?> c = Class.forName("org.prgm.ChildClass");

// Getting fields of the class
Field[] allFields = c.getFields();
System.out.println("All Fields - " + Arrays.toString(allFields));

// Getting fields of the class
Field[] fields = c.getDeclaredFields();
System.out.println("Fields - " + Arrays.toString(fields));

Output

All Fields - []
Fields - [private int org.prgm.ChildClass.value]

Since ChildClass.java doesn’t have any accessible public field (inherited or its own) so no value is returned for getFields() method.

There is one private field in ChildClass.java, getDeclaredFields() method shows that field.

Getting constructors of the class

There are four methods for getting the constructors of the class. If you want Constructor object for any specific constructor, then you can use getConstructor(Class<?>... parameterTypes) or getDeclaredConstructor(Class<?>... parameterTypes) method. To get all the constructors of the class you can use following two methods.

  • getDeclaredConstructors() - Returns an array of Constructor objects reflecting all the constructors declared by the class represented by this Class object. These are public, protected, default (package) access, and private constructors.
  • getConstructors()- Returns an array containing Constructor objects reflecting all the public constructors of the class represented by this Class object.
Class<?> c = Class.forName("org.prgm.ChildClass");

Constructor<?>[] constructors = c.getConstructors();
System.out.println("Constructors - " + Arrays.toString(constructors));
   
Constructor<?>[] Decconstructors = c.getDeclaredConstructors();
System.out.println("Declared constructors - " + Arrays.toString(Decconstructors));

Output

Constructors - [public org.prgm.ChildClass(java.lang.String,int)]
Declared constructors - [public org.prgm.ChildClass(java.lang.String,int)]

Since class ChildClass has only one public constructor so both methods are returning the same array of Constructor objects.

Getting methods of the class

There are four methods for getting the methods of the class. If you want Method object for any specific constructor, then you can use getMethod(String name, Class<?>... parameterTypes) or getDeclaredMethod(String name, Class<?>... parameterTypes) method. To get all the methods of the class you can use following two methods.

  • getDeclaredMethods() - Returns an array containing Method objects reflecting all the declared methods of the class or interface represented by this Class object, including public, protected, default (package) access, and private methods, but excluding inherited methods.
  • getMethods() - Returns an array containing Method objects reflecting all the public methods of the class or interface represented by this Class object, including those declared by the class or interface and those inherited from superclasses and superinterfaces.
Class<?> c = Class.forName("org.prgm.ChildClass");

// Getting all methods (even inherited) of the class
Method[] methods = c.getMethods();
System.out.println("All Methods - " + Arrays.toString(methods));
   
// Getting methods of the class
methods = c.getDeclaredMethods();
System.out.println("Class Methods - " + Arrays.toString(methods));

Output

All Methods - [public void org.prgm.ChildClass.showValue(), public java.lang.String org.prgm.Parent.getName(), 
public void org.prgm.Parent.displayName(), public final void java.lang.Object.wait() throws java.lang.InterruptedException, 
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException, 
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException, 
public boolean java.lang.Object.equals(java.lang.Object), public java.lang.String java.lang.Object.toString(), 
public native int java.lang.Object.hashCode(), public final native java.lang.Class java.lang.Object.getClass(), 
public final native void java.lang.Object.notify(), public final native void java.lang.Object.notifyAll()]

Class Methods - [public void org.prgm.ChildClass.showValue()]

Here you can see how getMethods() shows all the methods even inherited one.

Getting annotations

You can use following two methods to get information about the annotations.

  • getAnnotations() - Returns annotations that are present on this element. If there are no annotations present on this element, the return value is an array of length 0.
  • getDeclaredAnnotations() - Returns annotations that are directly present on this element. This method ignores inherited annotations. If there are no annotations directly present on this element, the return value is an array of length 0.
Class<?> c = Class.forName("org.prgm.ChildClass");
   
Annotation[] annotations = c.getAnnotations();
System.out.println("Annotations - " + Arrays.toString(annotations));
   
Annotation[] Decannotations = c.getDeclaredAnnotations();
System.out.println("Annotations - " + Arrays.toString(Decannotations));

Output

Annotations - []
Annotations - []

Since there are no annotations present on the class so array length is zero for both methods. Note that these methods can be used in the same way with the object of Method or Field class to get annotations present on a method or a field.

That's all for this topic Reflection in Java-class. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Reflection in Java
  2. Reflection in Java - Field
  3. Reflection in Java - Constructor
  4. Generating getters and setters using Reflection - Java Program
  5. Nested class and Inner class in Java

You may also like -

>>>Go to Java advance topics page