反射学习记录

本文详细介绍了Java反射机制,包括获取Class对象的三种方式,以及如何利用反射获取和使用构造方法、成员变量和成员方法。通过实例展示了反射在创建对象、调用方法和修改属性上的应用,同时提供了多个实战练习,加深理解。
摘要由CSDN通过智能技术生成

反射概述
Java反射机制:是指在运行时去获取一个类的变量和方法信息。然后通过获取到的信息来创建对象,调用方法的一种机制。由于这种动态性,可以极大的增强程序的灵活性,程序不用在编译期就完成确定,在运行期仍然可以扩展。

获取Class类的对象
我们要想通过反射去使用一个类,首先我们要获取到该类的字节码文件对象,也就是类型为Class类型的对象

以下三种方式可以获取Class类型的对象
1.使用类的class属性来获取该类对应的Class对象。举例: Student.class将会返回Student类对应的Class对象

2.调用对象的getClass()方法,返回该对象所属类对应的Class对象
        该方法是Object类中的方法,所有的Java对象都可以调用该方法

3.使用Class类中的静态方法forName(String className),该方法需要传入字符串参数,该字符串参数的值是某个类的全路径,也就是完整包名的路径
 

package fanshe;
/*
 * 以下三种方式可以获取Class类型的对象
	1.使用类的class属性来获取该类对应的Class对象。举例: Student.class将会返回Student类对应的Class对象	
	2.调用对象的getClass()方法,返回该对象所属类对应的Class对象
	   该方法是Object类中的方法,所有的Java对象都可以调用该方法	
	3.使用Class类中的静态方法forName(String className),该方法需要传入字符串参数,该字符串参数的值是某个类的全路径,也就是完整包名的路径
 */
public class Demo1 {
	public static void main(String[] args) throws ClassNotFoundException {
		//使用类的class属性来获取该类对应的Class对象
		Class<Student> c1=Student.class;
		System.out.println(c1);      //class fanshe.Student
		Class<Student> c2=Student.class;
		System.out.println(c1==c2);  //true
		//调用对象的getClass()方法,返回该对象所属类对应的Class对象
		Student s=new Student();
		Class<? extends Student> c3=s.getClass();
		System.out.println(c1==c3);  //true
		//使用Class类中的静态方法forName(String className)
		Class<?> c4=Class.forName("fanshe.Student");
		System.out.println(c1==c4);  //true
	}

}

反射获取构造方法并使用

Class类中用于获取构造方法的方法:
Constructor<?>[]getConstructors():返回所有公共构造方法对象的数组

Constructor<?>l[getDeclaredConstructors():返回所有构造方法对象的数组

Constructor<T> getConstructor(Class<? > ... parameterTypes):返回单个公共构造方法对象

Constructor<T> getDeclaredConstructor(Class<?>...parameterTypes):返回单个构造方法对象
Constructor类中用于创建对象的方法:
T newInstance(Object... initargs):根据指定的构造方法创建对象

package fanshe;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/*
 * Class类中用于获取构造方法的方法:
	Constructor<?>[]getConstructors():返回所有公共构造方法对象的数组
	Constructor<?>l[getDeclaredConstructors():返回所有构造方法对象的数组
	Constructor<T> getConstructor(Class<? > ... parameterTypes):返回单个公共构造方法对象
	Constructor<T> getDeclaredConstructor(Class<?>...parameterTypes):返回单个构造方法对象
	Constructor类中用于创建对象的方法:
	T newInstance(Object...initargs):根据指定的构造方法创建对象
 */
public class Demo2 {

	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
		//获取Class对象
		Class<?> c=Class.forName("fanshe.Student");
        //Constructor<?>[]getConstructors():返回所有公共构造方法对象的数组
		Constructor<?>[] cons=c.getConstructors();
		for(Constructor cons1:cons) {
			System.out.println(cons1);
		}
		System.out.println("------------------");
		//Constructor<?>[]getDeclaredConstructors():返回所有构造方法对象的数组
		Constructor<?>[] dcons=c.getDeclaredConstructors();
		for(Constructor dcons1:dcons) {
			System.out.println(dcons1);
		}
		System.out.println("------------------");
		//Constructor<T> getConstructor(Class<? > ... parameterTypes):返回单个公共构造方法对象
		//参数:你要获取的构造方法的参数的个数和数据类型对应的字节码文件对象
		Constructor<?> con=c.getConstructor();
		//T newInstance(Object...initargs):根据指定的构造方法创建对象
		Object obj=con.newInstance();
		System.out.println(obj);
	}

}

Student类:

package fanshe;

public class Student {
    private String name;
    int age;
    public String address;
    
    public Student () {}
    private Student (String name) {
    	this.name=name;
    }
    Student (String name,int age){
    	this.name=name;
    	this.age=age;
    }
    public Student (String name,int age,String address) {
    	this.name=name;
    	this.age=age;
    	this.address=address;
    }
    private void function() {
    	System.out.println( "function" );
    	}
    	public void method1() {
    	System.out.println( "method" );
    	}
    	public void method2(String s) {
    	System.out.println( "method : " + s);
    	}
    	public String method3(String s, int i) {
    	return s + "," +i;
    	}
		@Override
		public String toString() {
			return "Student [name=" + name + ", age=" + age + ", address=" + address + "]";
		}
       
}

练习1:通过反射实现如下操作
Student s = new Student("林青霞",30,"西安");

System.out.printIn(s);
 

package fanshe;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class Demo4 {

	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalArgumentException, InvocationTargetException, IllegalAccessException {
		//获取Class对象
		Class<?> c=Class.forName("fanshe.Student");
		//Constructor<T> getConstructor(Class<? > ... parameterTypes):返回单个公共构造方法对象
		Constructor<?> con=c.getConstructor(String.class,int.class,String.class);//基本数据类型也可以通过.Class得到对应的Class类型

		//T newInstance(Object...initargs):根据指定的构造方法创建对象
        Object obj= con.newInstance("林青霞",30,"福州");
        System.out.println(obj);
	}

}

练习2:通过反射实现如下操作
Student s = new Student("林青霞");

System.out.printIn(s);

public void setAccessible(boolean flag):值为true,取消访问检查

package fanshe;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class Demo3 {

	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		//获取Class对象
		Class<?> c=Class.forName("fanshe.Student");
		//Constructor<T> getDeclaredConstructor(Class<?>...parameterTypes):返回单个构造方法对象 
		Constructor<?> con=c.getDeclaredConstructor(String.class);
		//暴力反射
		//public void setAccessible (boolean flag):值为true,取消访问检查
		con.setAccessible(true);
		Object obj=con.newInstance("林青霞");
		System.out.println(obj);
	}

}

反射获取成员变量并使用

Class类中用于获取成员变量的方法
Field[] getFields():返回所有公共成员变量对象的数组

Field[] getDeclaredFields():返回所有成员变量对象的数组

Field getField(String name):返回单个公共成员变量对象

Field getDeclaredField(String name):返回单个成员变量对象

Field类中用于给成员变量赋值的方法
void set(Object obj, Object value):给obj对象的成员变量赋值为value

package fanshe;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

/*
 *  Field[] getFields():返回所有公共成员变量对象的数组
	Field[] getDeclaredFields():返回所有成员变量对象的数组
	Field getField(String name):返回单个公共成员变量对象
	Field getDeclaredField(String name):返回单个成员变量对象
	Field类中用于给成员变量赋值的方法
	void set(Object obj, Object value):给obj对象的成员变量赋值为value
 */
public class Demo5 {
	public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		//获取Class对象
		Class<?> c=Class.forName("fanshe.Student");
        //Field[] getFields():返回所有公共成员变量对象的数组
		Field[] gfs=c.getFields();
		for(Field gfs1:gfs) {
			System.out.println(gfs1);
		}
		System.out.println("-----------------");
		//Field[] getDeclaredFields():返回所有成员变量对象的数组
		Field[] gdfs=c.getDeclaredFields();
		for(Field gdfs1:gdfs) {
			System.out.println(gdfs1);
		}
		System.out.println("-----------------");
		//Field getField(String name):返回单个公共成员变量对象
		Field gfd=c.getField("address");
		//获取无参构造方法创建对象
		//Constructor<T> getConstructor(Class<? > ... parameterTypes):返回单个公共构造方法对象
		Constructor<?> con=c.getConstructor();
		Object obj=con.newInstance();
		//Field类中用于给成员变量赋值的方法
	    //void set(Object obj, Object value):给obj对象的成员变量赋值为value
		gfd.set(obj, "福州");//给obj的成员变量gfd赋值为福州
		System.out.println(obj);
	}

}

Student类:

package fanshe;

public class Student {
    private String name;
    int age;
    public String address;
    
    public Student () {}
    private Student (String name) {
    	this.name=name;
    }
    Student (String name,int age){
    	this.name=name;
    	this.age=age;
    }
    public Student (String name,int age,String address) {
    	this.name=name;
    	this.age=age;
    	this.address=address;
    }
    private void function() {
    	System.out.println( "function" );
    	}
    	public void method1() {
    	System.out.println( "method" );
    	}
    	public void method2(String s) {
    	System.out.println( "method : " + s);
    	}
    	public String method3(String s, int i) {
    	return s + "," +i;
    	}
		@Override
		public String toString() {
			return "Student [name=" + name + ", age=" + age + ", address=" + address + "]";
		}
       
}

练习:通过反射实现如下操作
Student s = new Student(;s.name = "林青霞");
s.age = 30;
s.address ="福州";                                                                                                  System.out.println(s);

package fanshe;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

public class Demo6 {

	public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		//获取Class对象
		Class<?> c=Class.forName("fanshe.Student");
		//获取无参构造方法创建对象
		//Constructor<T> getConstructor(Class<? > ... parameterTypes):返回单个公共构造方法对象
		Constructor con=c.getConstructor();
		Object obj=con.newInstance();
		//------------name
		//Field getDeclaredField(String name):返回单个成员变量对象
		Field fname=c.getDeclaredField("name");
		//暴力反射
		//public void setAccessible (boolean flag):值为true,取消访问检查
		fname.setAccessible(true);
		fname.set(obj, "林青霞");
		//------------age
		Field fage=c.getDeclaredField("age");
		fage.setAccessible(true);
		fage.set(obj, 30);
		//------------address
		Field fadd=c.getDeclaredField("address");
		fadd.setAccessible(true);
		fadd.set(obj, "福州");
		//------------输出
		System.out.println(obj);
	}

}

 Student类:

package fanshe;

public class Student {
    private String name;
    int age;
    public String address;
    
    public Student () {}
    private Student (String name) {
    	this.name=name;
    }
    Student (String name,int age){
    	this.name=name;
    	this.age=age;
    }
    public Student (String name,int age,String address) {
    	this.name=name;
    	this.age=age;
    	this.address=address;
    }
    private void function() {
    	System.out.println( "function" );
    	}
    	public void method1() {
    	System.out.println( "method" );
    	}
    	public void method2(String s) {
    	System.out.println( "method : " + s);
    	}
    	public String method3(String s, int i) {
    	return s + "," +i;
    	}
		@Override
		public String toString() {
			return "Student [name=" + name + ", age=" + age + ", address=" + address + "]";
		}
       
}

反射获取成员方法并使用

Class类中用于获取成员方法的方法:
Method[] getMethods():返回所有公共成员方法对象的数组,包括继承的
Method[] getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的
Method getMethod(String name, Class<?> ... parameterTypes)∶返回单个公共成员方法对象Method getDeclaredMethod(String name, Class<?>... parameterTypes):返回单个成员方法对象
Method类中用于调用成员方法的方法
Object invoke(Object obj, Object..args):调用obj对象的成员方法,参数是args,返回值是Object类型

package fanshe;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/*
 *  Method[] getMethods():返回所有公共成员方法对象的数组,包括继承的
	Method[] getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的
	Method getMethod(String name, Class<?> ... parameterTypes)∶返回单个公共成员方法对象
	Method getDeclaredMethod(String name, Class<?>... parameterTypes):返回单个成员方法对象
	Method类中用于调用成员方法的方法
	Object invoke(Object obj, Object..args):调用obj对象的成员方法,参数是args,返回值是Object类型
 */
public class Demo7 {
	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		//获取Class对象
		Class<?> c=Class.forName("fanshe.Student");
        //Method[] getMethods():返回所有公共成员方法对象的数组,包括继承的
		Method[] m1=c.getMethods();
		for(Method m11:m1) {
			System.out.println(m11);
		}
		System.out.println("------------");
		//Method[] getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的
		Method[] md1=c.getDeclaredMethods();
		for(Method md11:md1) {
			System.out.println(md11);
		}
		System.out.println("------------");
		//Method getMethod(String name, Class<?> ... parameterTypes)∶返回单个公共成员方法对象
		Method m=c.getMethod("method1");
		//获取无参构造方法创建对象
		//Constructor<T> getConstructor(Class<? > ... parameterTypes):返回单个公共构造方法对象
		Constructor<?> con=c.getConstructor();
		Object obj=con.newInstance();
		//Method类中用于调用成员方法的方法
		//Object invoke(Object obj, Object..args):调用obj对象的成员方法,参数是args,返回值是Object类型
		m.invoke(obj);
	}

}

 Student类:

package fanshe;

public class Student {
    private String name;
    int age;
    public String address;
    
    public Student () {}
    private Student (String name) {
    	this.name=name;
    }
    Student (String name,int age){
    	this.name=name;
    	this.age=age;
    }
    public Student (String name,int age,String address) {
    	this.name=name;
    	this.age=age;
    	this.address=address;
    }
    private void function() {
    	System.out.println( "function" );
    	}
    	public void method1() {
    	System.out.println( "method" );
    	}
    	public void method2(String s) {
    	System.out.println( "method : " + s);
    	}
    	public String method3(String s, int i) {
    	return s + "," +i;
    	}
		@Override
		public String toString() {
			return "Student [name=" + name + ", age=" + age + ", address=" + address + "]";
		}
       
}

练习:通过反射实现如下操作·
student s = new Student();

s.method1();
s.method2("林青霞");
String ss = s.method3("林青霞",30);                                                               System.out.printIn(ss);
s.function();

package fanshe;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Demo8 {

	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		//获取Class对象
		Class<?> c=Class.forName("fanshe.Student");
		//获取无参构造方法创建对象
		Constructor<?> con=c.getConstructor();
		Object obj=con.newInstance();
		//--------------------s.method1();
        //Method getMethod(String name, Class<?> ... parameterTypes)∶返回单个公共成员方法对象
		Method m1=c.getMethod("method1");
		//Method类中用于调用成员方法的方法
		//Object invoke(Object obj, Object..args):调用obj对象的成员方法,参数是args,返回值是Object类型
		m1.invoke(obj);
		//-------------------s.method2("林青霞");
	    //Method getMethod(String name, Class<?> ... parameterTypes)∶返回单个公共成员方法对象
		Method m2=c.getMethod("method2", String.class);
		m2.invoke(obj, "林青霞");
		//-------------------String ss = s.method3("林青霞",30); System.out.printIn(ss);
		Method m3=c.getMethod("method3",String.class,int.class);
		Object o=m3.invoke(obj, "林青霞",30);
		System.out.println(o);
		//------------------s.function();
		Method f=c.getDeclaredMethod("function");
		f.setAccessible(true);
		f.invoke(obj);
		
	}

}

  Student类:

package fanshe;

public class Student {
    private String name;
    int age;
    public String address;
    
    public Student () {}
    private Student (String name) {
    	this.name=name;
    }
    Student (String name,int age){
    	this.name=name;
    	this.age=age;
    }
    public Student (String name,int age,String address) {
    	this.name=name;
    	this.age=age;
    	this.address=address;
    }
    private void function() {
    	System.out.println( "function" );
    	}
    	public void method1() {
    	System.out.println( "method" );
    	}
    	public void method2(String s) {
    	System.out.println( "method : " + s);
    	}
    	public String method3(String s, int i) {
    	return s + "," +i;
    	}
		@Override
		public String toString() {
			return "Student [name=" + name + ", age=" + age + ", address=" + address + "]";
		}
       
}

反射练习之越过泛型检查
有一个ArrayList<Integer>集合,现要在这个集合中添加一个字符串数据,如何实现?

package fanshe;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

public class Demo9 {

	public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		ArrayList<Integer> array=new ArrayList<Integer>();
		Class<? extends ArrayList> c=array.getClass();
		Method m=c.getMethod("add",Object.class);
		m.invoke(array,"hello");
		m.invoke(array, "world");
		System.out.println(array);
	}

}

反射练习之运行配置文件指定内容

package fanshe;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

public class Demo10 {
	public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		/*
		 * Class.txt
		 * className:xxxx
           methodName:xxxx
		 */
         //加载数据
		Properties pro=new Properties();
		FileReader fr=new FileReader("C:\\DW\\Class.txt");
		pro.load(fr);
		fr.close();
		/*
		 * className:fanshe.S
           methodName:study
		 */
		String className=pro.getProperty("className");   //拿到fanshe.S
		String methodName=pro.getProperty("methodName"); //拿到study
		//通过反射来使用
		Class<?> c=Class.forName(className);
		Constructor<?> con=c.getConstructor();
		Object obj=con.newInstance();
		Method m=c.getMethod(methodName);
		m.invoke(obj);
	}

}

S类:

package fanshe;

public class S {
   public void study() {
	   System.out.println("好好学习,天天向上");
   }
}

T类:

package fanshe;

public class T {
     public void teach() {
    	 System.out.println("老师");
     }
}

Class.txt:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值