- Programming Examples
- Are you a Programmer or Application Developer or a DBA? Take a cup of coffee, sit back and spend few minutes here 🙂
- Java Reflection: Finding Instance Type
- 1. Type Detection Through Java Reflection
- 2. What is Java class, Class and Instance?
- 3. The IOrg Interface
- Retrieving Class Objects
- Object.getClass()
- The .class Syntax
- Class.forName()
- TYPE Field for Primitive Type Wrappers
- Methods that Return Classes
- Java find class reflection
Programming Examples
Are you a Programmer or Application Developer or a DBA? Take a cup of coffee, sit back and spend few minutes here 🙂
Java Reflection: Finding Instance Type
1. Type Detection Through Java Reflection
Reflection in Java is an approach of RTTI (Run Time Type Identification) in terms of C++ language. In addition, Java allows invoking the type members also. For example, once we find the type at Run-time we can also access its members.
One may think how we do not know a type at compile time. But in reality when we write code there are significant circumstances where we may not know the instance type. The Polymorphism is one good example in which we may not know the instance type at compile time. Through RTTI technique, we can identify it at Run-time on the fly. Reflection in Java helps in designing robust and configurable applications.
In this example, we will create two classes and one Interface. Then we will get its type name at Run-time.
2. What is Java class, Class and Instance?
A class in Java is a template definition of an object. Based on the class template one can create one or more objects. We call these objects as Instances.
A Class (Note the capital C) in Java is an in-built class (Template definition) that defines object types. Application developers cannot create an instance from it. However, Java will create the instances of it when an object of any type is loaded into memory at run-time. For Example, when Java application creates a class instance called SecurityFile, then Java creates a class instance of Class to denote its type.
From the instance of an object of type Class, we can fetch run-time information of the class type. For each type, Java can load only one Class instance in memory and we can get the RTTI from it. For Example, even if user created ten objects of SecurityFile class, Java creates only one instance of the Class for the class type SecurityFile. This one object is enough to get the type information about the object SecurityFile.
OK. We will start our example and learn further while we proceed.
3. The IOrg Interface
A Type in Java can represent an Array, Enumeration, Interface, class instances etc,. Now, we will create an Interface of type IOrg . Below is the code that defines the IOrg interface:
Retrieving Class Objects
The entry point for all reflection operations is java.lang.Class . 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 . 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 an instance of an object is available, then the simplest way to get its Class is to invoke Object.getClass() . Of course, this only works for reference types which all inherit from Object . Some examples follow.
Class c = System.console().getClass();
There is a unique console associated with the virtual machine which is returned by the static method System.console() . The value returned by getClass() is the Class corresponding to java.io.Console .
enum E < A, B >Class c = A.getClass();
A is an instance of the enum E ; thus getClass() returns the Class corresponding to the enumeration type E .
byte[] bytes = new byte[1024]; Class c = bytes.getClass();
Since arrays are Objects , it is also possible to invoke getClass() on an instance of an array. The returned Class corresponds to an array with component type byte .
import java.util.HashSet; import java.util.Set; Set s = new HashSet(); Class c = s.getClass();
In this case, java.util.Set is an interface to an object of type java.util.HashSet . The value returned by getClass() is the class corresponding to java.util.HashSet .
The .class Syntax
If the type is available but there is no instance then it is possible to obtain a Class by appending «.class» to the name of the type. This is also the easiest way to obtain the Class for a primitive type.
boolean b; Class c = b.getClass(); // compile-time error Class c = boolean.class; // correct
Note that the statement boolean.getClass() would produce a compile-time error because a boolean is a primitive type and cannot be dereferenced. The .class syntax returns the Class corresponding to the type boolean .
Class c = java.io.PrintStream.class;
The variable c will be the Class corresponding to the type java.io.PrintStream .
The .class syntax may be used to retrieve a Class corresponding to a multi-dimensional array of a given type.
Class.forName()
If the fully-qualified name of a class is available, it is possible to get the corresponding Class using the static method Class.forName() . This cannot be used for primitive types. The syntax for names of array classes is described by Class.getName() . This syntax is applicable to references and primitive types.
Class c = Class.forName("com.duke.MyLocaleServiceProvider");
This statement will create a class from the given fully-qualified name.
Class cDoubleArray = Class.forName("[D"); Class cStringArray = Class.forName("[[Ljava.lang.String;");
The variable cDoubleArray will contain the Class corresponding to an array of primitive type double (that is, the same as double[].class ). The cStringArray variable will contain the Class corresponding to a two-dimensional array of String (that is, identical to String[][].class ).
TYPE Field for Primitive Type Wrappers
The .class syntax is a more convenient and the preferred way to obtain the Class for a primitive type; however there is another way to acquire the Class . Each of the primitive types and void has a wrapper class in java.lang that is used for boxing of primitive types to reference types. Each wrapper class contains a field named TYPE which is equal to the Class for the primitive type being wrapped.
There is a class java.lang.Double which is used to wrap the primitive type double whenever an Object is required. The value of Double.TYPE is identical to that of double.class .
Void.TYPE is identical to void.class .
Methods that Return Classes
There are several Reflection APIs which return classes but these may only be accessed if a Class has already been obtained either directly or indirectly.
Class.getSuperclass() Returns the super class for the given class.
Class c = javax.swing.JButton.class.getSuperclass();
The super class of javax.swing.JButton is javax.swing.AbstractButton . Class.getClasses() Returns all the public classes, interfaces, and enums that are members of the class including inherited members.
Class[] c = Character.class.getClasses();
Character contains two member classes Character.Subset and Character.UnicodeBlock . Class.getDeclaredClasses() Returns all of the classes interfaces, and enums that are explicitly declared in this class.
Class[] c = Character.class.getDeclaredClasses();
import java.lang.reflect.Field; Field f = System.class.getField("out"); Class c = f.getDeclaringClass();
public class MyClass < static Object o = new Object() < public void m() <>>; static Class = o.getClass().getEnclosingClass(); >
The declaring class of the anonymous class defined by o is null . Class.getEnclosingClass() Returns the immediately enclosing class of the class.
Class c = Thread.State.class().getEnclosingClass();
public class MyClass < static Object o = new Object() < public void m() <>>; static Class = o.getClass().getEnclosingClass(); >
Java find class reflection
Боже, хоть одна всеняемая статья про Рефлекшн для новичков. А то, другие авторы сразу выввливают кучу методов, без объяснений для нубов. Спасибо, автор!
Грамотно написанный класс в Java: — У меня всё как надо, всё что нужно скрыть, помечено Private, я вообще не вызываю багов вовремя работы программы. 💪😎👍 Reflection API: — 😂 Я вас умоляю, не смешите мои подковы методы).
На собеседовании : — Reflection API, для чего он нужен? — Он позволяет наиболее циничный способом попрать принцип инкапсуляции в java.
Вызов метода мяу обычным способом : Кот, мяукни! Вызов метода мяу через рефлексию : Мяу, прозвучи от того кота!
clazz = Class.forName(Cat.class.getName());
Вместо того, чтобы сразу получить объект класса, мы сначала получаем имя класса (которое нам известно), а потом по нему получаем объект класса. Или это как-то связано с полным именем (learn.javarush.Cat) ?
Я статью только начал читать, но уже появился вопрос, причём, видимо, элементарный: если класс Cat наследует класс Animal, то зачем в наследнике повторять те же поля private String name; private int age; Они же ему переходят по наследству? Вопрос второй: как понять эти строки Class clazz = Class.forName(className); Cat cat = (Cat) clazz.newInstance(); Если стоит задача создать объект класса, чьё имя на момент компиляции неизвестно, то откуда в тексте программы это самое неизвестное имя? Я бы мог представить такую строку: Object obj = clazz.newInstance(); Она была бы универсальной для любого типа. И она есть в этом же коде ниже, в методе createObject(), но он же не вызывается вроде. Вызывается createCat()
вернулся сюда из 34 уровня лекции 8 задачи 2, запомните как создать обж с конструктором который принимает аргумент.
На этом наша лекция подошла к концу! Она получилась довольно большой, но сегодня ты узнал много нового :)
И сегодня, и вчера, и позавчера. Смог прожевать только за три вечера. Не уверен, что прожевал тщательно, и не случится изжоги. 🤣