反射的基本原理:反射的机制是通过类加载器将字节码文件读入到内存中,然后通过解析器在内存中解析出这个类的所有东西,当我们需要用到的时候我们可以拿出来使用。
一、反射一个类的构造函数
person类
package com.cn.ljh.reflect;
public class Person {
private String name;
private int age;
//无参构造函数
public Person(){
System.out.println("无参构造函数");
}
//一个参数的构造函数
public Person(String name){
this.name = name;
System.out.println("一个参数构造函数"+name);
}
//两个构造函数
public Person(String name,int age){
this.name = name;
this.age = age;
System.out.println(name+"="+age);
}
//私有构造函数
private Person(int age){
this.age = age;
System.out.println("私有的构造函数"+age);
}
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;
}
}
反射person类中的构造函数基本操作
package com.cn.ljh.reflect;
import java.lang.reflect.Constructor;
/**
* 通过反射获取构造函数
* @author lijunhong
*
*/
public class Test1 {
public static void main(String[] args) throws Exception {
// test1();
// test2();
// test3();
test4();
}
//获取字节码文件的三种方式
public static void test() throws Exception{
//1.通过类的全名获取
Class clas = Class.forName("com.cn.ljh.reflect.Person");
//2.通过类名获取
Class p = Person.class;
//3.通过对象获取
Person person = new Person();
Class cl = person.getClass();
}
//通过反射获取无参构造函数(可以使用上面三种方式获取字节码)
public static void test1() throws Exception{
//获得(Person)字节码文件
Class clas = Class.forName("com.cn.ljh.reflect.Person");
//得到无参构造函数
Constructor con = clas.getConstructor(null);
//通过无参构造函数创建实例
Person persong = (Person) con.newInstance(null);
}
//通过反射获取带一个参数的构造函数
public static void test2() throws Exception{
//获得(Person)字节码文件
Class clas = Person.class;
//得到有一个参数的构造函数
Constructor con = clas.getConstructor(String.class);
//创建带有一个参数的构造函数的实例
Person p = (Person) con.newInstance("张三");
}
//通过反射获取带有两个参数的构造函数
public static void test3() throws Exception{
Class clas = Class.forName("com.cn.ljh.reflect.Person");
Constructor con = clas.getConstructor(String.class,int.class);
con.newInstance("李白",100);
}
//通过反射获取私有的构造函数
public static void test4() throws Exception{
Class clas = Class.forName("com.cn.ljh.reflect.Person");
//获取私有的构造函数
Constructor con = clas.getDeclaredConstructor(int.class);
con.setAccessible(true);//这里设置为true获得私有方法
con.newInstance(100);
}
}
二、反射一个类的方法
person2类
package com.cn.ljh.reflect;
public class Person2 {
private String name;
private int age;
public Person2(){
}
public void eat1(){
System.out.println("无参,无返回值方法");
}
public void eat2(String food,String toos){
System.out.println("用"+toos+"(有参,无返回值)吃"+food);
}
public String eat3(){
return "返回值方法";
}
private void eat4(){
System.out.println("私有方法(无返回值,无参数)");
}
public static void main(String[] args){
System.out.println("main函数");
for(String s:args){
System.out.println(s);
}
}
}
反射person2类中的方法基本操作
package com.cn.ljh.reflect;
import java.lang.reflect.Method;
/**
* 通过反射获取方法
* @author lijunhong
*
*/
public class Test2 {
public static void main(String[] args) throws Exception {
// test1();
// test2();
// test3();
// test4();
test5();
}
//反射无参无返回值方法
public static void test1() throws Exception{
//获取(Person1)字节码文件
Class clas = Class.forName("com.cn.ljh.reflect.Person2");
//通过无参构造函数创建对象
Person2 p = (Person2) clas.newInstance();
//获得方法(通过方法名字和参数反射)
Method m = clas.getMethod("eat1", null);
//通过对象和参数调用方法
m.invoke(p, null);
}
//反射有参无返回值方法(多参数)
public static void test2() throws Exception{
Class clas = Class.forName("com.cn.ljh.reflect.Person2");
Person2 p = (Person2) clas.newInstance();
Method m = clas.getMethod("eat2", String.class,String.class);
m.invoke(p, "香蕉","手");
}
//反射有返回值方法
public static void test3() throws Exception{
Class clas = Class.forName("com.cn.ljh.reflect.Person2");
Method m = clas.getMethod("eat3", null);
Person2 p = (Person2) clas.newInstance();
String value = (String) m.invoke(p, null);
System.out.println(value);
}
//反射私有方法
public static void test4() throws Exception{
Class clas = Class.forName("com.cn.ljh.reflect.Person2");
Method m = clas.getDeclaredMethod("eat4", null);
Person2 p = (Person2) clas.newInstance();
//设置true得到私有方法
m.setAccessible(true);
m.invoke(p, null);
}
//反射main方法
public static void test5() throws Exception{
Class clas = Class.forName("com.cn.ljh.reflect.Person2");
Method m = clas.getMethod("main", String[].class);
Person2 p = (Person2) clas.newInstance();
//将String数组封装成Object数组,使其Object中只有一个元素,
//否则main方法会将其拆成两个参数,而不是一个数组元素
//还可以直接封装成object类型的
// m.invoke(p,new Object[]{(new String[]{"1","2"})});
//封装成object类型的
m.invoke(p, (Object) new String[]{"1","2"});
}
}
三、反射一个类的字段(成员变量)
student类
package com.cn.ljh.reflect;
public class Student {
private String name;
public int age;
private static int grade;
public Student(){
}
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;
}
public static int getGrade() {
return grade;
}
public static void setGrade(int grade) {
Student.grade = grade;
}
}
反射一个类的字段的基本操作
package com.cn.ljh.reflect;
import java.lang.reflect.Field;
/**
* 通过反射获取字段
* @author lijunhong
*
*/
public class Test3 {
public static void main(String[] args) throws Exception {
// test1();
test2();
// test3();
}
//获取私有字段(同时操作name字段)
public static void test1() throws Exception{
//获得student字节码文件
Class clas = Class.forName("com.cn.ljh.reflect.Student");
//获得字段
Field f = clas.getDeclaredField("name");
//设置true拿到私有成员
f.setAccessible(true);
//创建对象
Student s = (Student) clas.newInstance();
//设置name的值
f.set(s, "张三");
//获得name的值
String name = (String) f.get(s);
System.out.println(name);
}
//获取公共的字段(同时操作age字段)
public static void test2() throws Exception{
Class clas = Class.forName("com.cn.ljh.reflect.Student");
Student s = (Student) clas.newInstance();
Field f = clas.getField("age");
f.set(s, 12);
System.out.println(f.get(s));
}
//获取私有的静态字段(同时操作grade字段)
public static void test3() throws Exception{
Class clas = Class.forName("com.cn.ljh.reflect.Student");
Student s = (Student) clas.newInstance();
s.getGrade();
s.setGrade(12);
}
}
记录学习的每一步,记录每一次的成长!!!!