一.Java反射:
(2)反射常用的Java 类型
Class类—可获取类和类的成员信息
Field类—可访问类的属性
Method类—可调用类的方法
Constructor类—可调用类的构造方法
(3) 反射的基本步骤
1.导入java.lang.reflect.*
2.获得需要操作的类的Java.lang.Class对象
3.调用Class的方法获取Field、Method等对象
4.使用反射API进行操作 (设置属性﹑调用方法)
(4) Class类是Java 反射机制的起源和入口
1.每个类都有自己的Class 对象
2.用于获取与类相关的各种信息
3.提供了获取类信息的相关方法
4.Class类继承自Object类
(5) 使用反射
public class TestReflect1 {
public static void main(String[] args) {
// 1)先创建对象
TestReflect1 test = new TestReflect1();
Class class1 = test.getClass();
System.out.println(class1);
// 2)类名.class
Class class2 = TestReflect1.class;
System.out.println(class2);
// 3)常用: Class.forName(包名.类名)
Class class3 = null;
try {
class3 = Class.forName("com.hlx.TestReflect1");
System.out.println(class3);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(class3.getDeclaredMethods()[0]);
System.out.println(class3.getDeclaredMethods()[1]);
//java.lang.IllegalArgumentException: object is not an instance of declaring class
try {
//*****获得对象**************/
Object object =class3.newInstance();
//System.out.println(object);
// 获得方法 第一个方法名: 第二个是:参数的类型
Method method = class3.getMethod("add", new Class[]{int.class, int.class,double.class});
// 通过invoke方法赋值: 第一个参数:对象名; 第二个是:参数值;
int sum = (int) method.invoke(object, 10, 20,34.57);
System.out.println(sum);
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public String show() {
return "you";
}
/**
* 两数求和的方法
*
* @param num1
* @param num2
* @return
*/
public int add(int num1, int num2,double num3) {
return (int)(num1 + num2+num3);
}
}
效果:
小结:
使用反射调用方法的步骤:
a)要想使用反射,首先需要获得待处理类或对象所对应的Class对象。
b)获取某个类或某个对象所对应的Class对象的常用的3种方式:
1)使用Class类的静态方法forName, => Class.forName(“java.lang.String”)
2)使用类的.class语法:String.class,=>Class<?> classType = InvokeTester.class;
3)使用对象的getClass()方法: =>String s = “aa”;Class<?> clazz=s.getClass();
c)通过获取的Class对象,产生一个实例 =>Object object =class3.newInstance();
d)获得想要调用方的Method对象,如Method addMethod = class3.getMethod("add", new Class[]{int.class,int.class});
e)通过获得的Method对象,在特定实例(对象)上调用方法:Object result = addMethod.invoke(object, new Object[]{1,2});
/**
* 客户类
*
* @author Administrator
*
*/
public class Customer {
public Long id;
private String name;
public int age;
private Long getId() {
return id;
}
public void setId(Long 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;
}
/**
* 有参数的构造方法
* @param name
* @param age
*/
public Customer(String name, int age) {
super();
this.name = name;
this.age = age;
}
/**
* 无参数的构造方法
*/
public Customer() {
super();
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return "Customer [name=" + name + ", age=" + age + "]";
}
}
测试:
public static void main(String[] args) throws Exception {
// 调用Constructor的newInstance()方法,适用所有构造方法
//1)Class.forName获得类;
Class class1 =Class.forName("com.hlx.Customer");
//2)获得构造方法对象 :参数==>类型
Constructor constructor= class1.getConstructor(String.class,int.class);
//3)给构造方法方法赋值 参数==>对应值
Object object=constructor.newInstance("熊二",20);
//4)输出数据
System.out.println((Customer)object);
System.out.println("\n----field------------");
//获得这个类中所有的属性
Field[] fields= class1.getDeclaredFields(); //所有的修饰符的public,protected,private...
// Field[] fields= class1.getFields(); 只能显示public
for (Field field : fields) {
System.out.println(field.getName()+"\t"+field.getType()+"\t"+field.getModifiers());
}
System.out.println("\n----method------------");
Method[] methods=class1.getDeclaredMethods(); //所有的修饰符的public,protected,private... 当前类中的方法
// Method[] methods=class1.getMethods(); //只能显示public,不仅是当前类中的,而且父类中的方法也显示
for (Method method : methods) {
System.out.println(method.getName()+"\t"+method.getReturnType()+"\t"+method.getModifiers());
}
// 调用Field 对象的方法进行取值或赋值操作
//给name赋值
Field field=class1.getDeclaredField("name");
//Exception in thread "main" java.lang.IllegalAccessException: Class com.hlx.TestCustomer can not access a member of class com.hlx.Customer with modifiers "private"
//解决:必须给它权限
field.setAccessible(true);
//设置值: 第一个参数:具体的对象; 第二个参数:name的值
field.set(object, "刘芳");
//获得name值
String string=(String) field.get(object);
System.out.println(string);
System.out.println("\n");
// 获得方法 第一个方法名: 第二个是:参数的类型
Method method=class1.getDeclaredMethod("getAge");
//创建对象
// Object obj=class1.newInstance();
// System.out.println(obj);
//动态调用方法
int age=(int) method.invoke(object);
System.out.println(age);
}
效果:
小结:
方法一:使用Class的newInstance()方法,仅适用于无参构造方法
//1)Class.forName获得类;
Class class1 =Class.forName("com.hlx.Customer");
Object obj=class1.newInstance();
方法二:调用Constructor的newInstance()方法,适用所有构造方法
//1)Class.forName获得类;
Class class1 =Class.forName("com.hlx.Customer");
//2)获得构造方法对象 :参数==>类型
Constructor constructor= class1.getConstructor(String.class,int.class);
//3)给构造方法方法赋值 参数==>对应值
Object object=constructor.newInstance("熊二",20);
Class类是Reflection API 中的核心类,它有以下方法
–getName():获得类的完整名字。
–getFields():获得类的public类型的属性。
–getDeclaredFields():获得类的所有属性。
–getMethods():获得类的public类型的方法。
–getDeclaredMethods():获得类的所有方法。
- getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes参数指定方法的参数类型。
- getConstructors():获得类的public类型的构造方法。
- getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes参数指定构造方法的参数类型。
- newInstance():通过类的不带参数的构造方法创建这个类的一个对象。