Java反射机制简介
JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
反射机制极大的提高了程序的灵活性和扩展性,降低模块的耦合性,提高自身的适应能力。使用反射机制能够在运行时构造一个类的对象、判断一个类所具有的成员变量和方法、调用一个对象的方法。它能动态编译和创建对象,极大的激发了编程语言的灵活性,强化了多态的特性,进一步提升了面向对象编程的抽象能力。
静态编译:在编译时确定类型,绑定对象。
动态编译:运行时确定类型,绑定对象。
下面,针对于对象的创建,我们首先来看一下工厂方法模式中如何进行对象的创建,即不使用反射机制时对象的创建。然后,再查看一下使用Java的反射机制,创建对象及进行相关操作。
设计模式中的工厂方法模式
工厂方法模式,创建一个工厂接口和创建多个工厂实现类,这样一旦需要增加新的功能,直接增加新的工厂类即可,不需要修改之前的代码。
Animal.java
public interface Animal{
public void sound();
}
Cat.java
public class Cat implements Animal{
@Override
public void sound() {
System.out.println("miao miao");
}
}
Dog.java
public class Dog implements Animal{
@Override
public void sound() {
System.out.println("wang wang");
}
}
工厂接口Factory.java
public interface Factory {
public Animal getInstance();
}
Cat工厂实现类CatFactory.java
public class CatFactory implements Factory{
@Override
public Animal getInstance() {
return new Cat();
}
}
Dog工厂实现类DogFactory.java
public class DogFactory implements Factory{
@Override
public Animal getInstance() {
return new Dog();
}
}
测试类Test.java
public class Test {
public static void main(String[] args) {
Factory factory=new CatFactory();//接口的引用指向实现类的对象
Animal animal=factory.getInstance();//接口的引用指向实现类的对象
animal.sound();
factory=new DogFactory();//接口的引用指向实现类的对象
animal=factory.getInstance();//接口的引用指向实现类的对象
animal.sound();
}
}
console控制台输出
总结:如果需要添加新的动物类,只需要编写一个实现类去实现Animal接口。同时,编写一个新添加动物的工厂实现类去实现Factory接口。拓展性比较好。
使用反射机制创建对象及相关操作
Student.java
package com.example.demo1;
public class Student {
private final static String TAG="student";
private int id;
private String name;
private int age;
public Student() {
}
private Student(String name,int age) {
this.name=name;
this.age=age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
}
private void myTestMethod(String studentName) {
System.out.println("my name is "+studentName);
}
}
反射逻辑所在类ReflectClass.java
package com.example.demo1;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectClass {
private final static String TAG="reflect";
//使用反射,创建对象
public static void reflectInstance() {
try {
Class<?> classStudent=Class.forName("com.example.demo1.Student");
Object objectStudent=classStudent.newInstance();
Student student=(Student)objectStudent;
student.setName("zhangsan");
student.setAge(12);
System.out.println(student.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
//使用反射,获取私有构造方法,创建对象
public static void reflectPrivateConstructor() {
try {
Class<?> classStudent=Class.forName("com.example.demo1.Student");
Constructor<?> declaredConstructorStudent = classStudent.getDeclaredConstructor(String.class,int.class);
// A value of false indicatesthat the reflected object should enforce Java language access checks.
declaredConstructorStudent.setAccessible(true);
Object objectStudent=declaredConstructorStudent.newInstance("lisi",13);
Student student=(Student)objectStudent;
System.out.println(student.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
//使用反射,获取私有属性
public static void reflectPrivateField() {
try {
Class<?> classStudent=Class.forName("com.example.demo1.Student");
Object objectStudent=classStudent.newInstance();
Field fieldTag = classStudent.getDeclaredField("TAG");
fieldTag.setAccessible(true);
String tag = (String) fieldTag.get(objectStudent);
System.out.println("TAG="+tag);
} catch (Exception e) {
e.printStackTrace();
}
}
//使用反射,获取私有方法
public static void reflectPrivateMethod() {
try {
Class<?> classStudent=Class.forName("com.example.demo1.Student");
Method methodStudent=classStudent.getDeclaredMethod("myTestMethod", String.class);
methodStudent.setAccessible(true);
Object objectStudent=classStudent.newInstance();
methodStudent.invoke(objectStudent, "wang wu");
} catch (Exception e) {
e.printStackTrace();
}
}
}
测试类MyReflectTest.java
package com.example.demo1;
public class MyReflectTest {
public static void main(String[] args) {
System.out.println("-----------reflectInstance()-----------");
ReflectClass.reflectInstance();
System.out.println("-----------reflectPrivateConstructor()-----------");
ReflectClass.reflectPrivateConstructor();
System.out.println("-----------reflectPrivateField()-----------");
ReflectClass.reflectPrivateField();
System.out.println("-----------reflectPrivateMethod()-----------");
ReflectClass.reflectPrivateMethod();
}
}
输出结果如下:
查看Java API中反射相关内容
https://www.oracle.com/technetwork/java/api-141528.html
具体编码时,可以参照API文档。在线Java API链接:https://docs.oracle.com/javase/8/docs/api/