定义:
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性。这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。
用途
通过反射,Java 代码可以发现有关已加载类的字段,方法和构造函数的信息,并可以在安全限制内对这些字段,方法和构造函数进行操作。
很多人都认为反射在实际Java中开发应用中并不广泛,其实不然。当我们在使用 IDE(如 IDEA/Eclipse)时,当我们输入一个对象或者类并调用它的属性和方法时,一按 (“.”)点号,编译器就会自动列出她的属性或方法,这里就会用到反射。
Java反射框架提供一下功能:
- 在运行时判定任意一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时判定任意一个类所具有的成员变量和方法
- 在运行时调用任意一个对象的方法
示例
为了演示反射的使用,首先构造一个与书籍相关的model——Book.java,然后了解获取Class类对象的三种方法,最后通过反射方法示例创建对象、反射私有构造方法、反射私有属性、反射私有方法
被反射类Book.java
public class Book{
private final static String TAG = "BookTag";
private String name;
private String author;
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
'}';
}
public Book() {
}
private Book(String name, String author) {
this.name = name;
this.author = author;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
private String declaredMethod(int index) {
String string = null;
switch (index) {
case 0:
string = "I am declaredMethod 0 !";
break;
case 1:
string = "I am declaredMethod 1 !";
break;
default:
string = "I am declaredMethod -1 !";
}
return string;
}
}
获取Class类对象的三种方法
在反射中,要获取一个类或调用一个类的方法,我们首先需要获取到该类的 Class 对象。
在 Java API 中,获取 Class 类对象的三种方法
方法一:使用 Class.forName 静态方法。当你知道该类的全路径名时,你可以使用该方法获取 Class 类对象。但可能抛出 ClassNotFoundException 异常
Class<?> classBook = Class.forName(“com.jourwon.reflect.Book”);
方法二:这种方法只适合在编译前就知道操作的 Class。直接通过 类名.class 的方式得到,该方法最为安全可靠,程序性能更高,这说明任何一个类都有一个隐含的静态成员变量 class
Class clz = Book.class;
方法三:使用类对象的 getClass() 方法。
Book book1 = new Book();
Class<? extends Book> book1Class = book1.getClass();
@Test
public void getClz() {
try {
// 方法一,使用 Class.forName 静态方法
Class<?> classBook = Class.forName("com.jourwon.reflect.Book");
// 方法二:直接通过 类名.class 的方式得到
Class clz = Book.class;
// 方法三:使用类对象的 getClass() 方法。
Book book1 = new Book();
Class<? extends Book> book1Class = book1.getClass();
System.out.println(classBook == clz);
System.out.println(classBook == book1Class);
} catch (Exception ex) {
ex.printStackTrace();
}
}
输出结果都是true,可以知道三种方法获取到的Class对象都是同一个对象