java反射使用

反射可以直接获得class对象,可以实现动态创建对象

1、获得class对象的方法

1、调用类的class属性


> Class<?> cls = String.class;//获得String的class对象
> System.out.println("String的class对象:"+cls); cls =
> int.class;//获得int类型的class对象 System.out.println("int的class对象:"+cls);

输出:

String的class对象:class java.lang.String
int的class对象:int

2、调用class中的forName(全类名)方法获得

try {
			Class<?> cls2 = Class.forName("java.util.Arrays");
			System.out.println("Arrays的class对象:"+cls2);
			
			//从控制台输入一个类名,获得该类名对应的类对象
			Scanner sca = new Scanner(System.in);
			String className = sca.nextLine();//给的是全类名
			Class<?> cls3 = Class.forName(className);
			System.out.println(className+"的classs对象"+cls3);
			sca.close();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

输出:

Arrays的class对象:class java.util.Arrays java.lang.Double
java.lang.Double的classs对象class java.lang.Double

完整代码:

public class ReflectDemo01 {
	public static void main(String[] args) {
		//"?"通配符,不论什么类型都能匹配
		Class<?> cls = String.class;//获得String的class对象
		System.out.println("String的class对象:"+cls);
		cls = int.class;//获得int类型的class对象
		System.out.println("int的class对象:"+cls);
		
		try {
			Class<?> cls2 = Class.forName("java.util.Arrays");
			System.out.println("Arrays的class对象:"+cls2);
			
			//从控制台输入一个类名,获得该类名对应的类对象
			Scanner sca = new Scanner(System.in);
			String className = sca.nextLine();//给的是全类名
			Class<?> cls3 = Class.forName(className);
			System.out.println(className+"的classs对象"+cls3);
			sca.close();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}

2、通过class对象创建类的实例

1、先创建一个类person

class Person{
	private String name;
	private Integer age;
	private String sex;
	public Person() {}
	public Person(String name, Integer age, String sex) {
		super();
		this.name = name;
		this.age = age;
		this.sex = sex;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]";
	}
}

2、获得Class对象

//获得class对象
Class<?> cls = Class.forName("reflect.Person");

3、创建实例
(1)通过无参构造创建的实例

Object instance = cls.newInstance();
System.out.println("无参构造创建对象:"+instance);//默认调用类中的toString()方法

输出:因为是无参构造,所以里面是空的

无参构造创建对象:Person [name=null, age=null, sex=null]

(2)通过有参构造创建实例
先获得构造函数,使用getConstructor(parameterTypes)方法,参数是构造函数参数的类型的class对象,是可变参数

Constructor<?> con = cls.getConstructor(String.class,Integer.class,String.class);

然后使用构造函数创建对象

Object o2 = con.newInstance("有参构造创建对象:"+"张三",100,"男");
System.out.println(o2);

输出:

Person [name=有参构造创建对象:张三, age=100, sex=男]

完整代码

public class RefiectDemo02 {
	public static void main(String[] args) {
		try {
			//获得class对象
			Class<?> cls = Class.forName("reflect.Person");
			/**
			 * 通过无参构造创建的对象实例
			 */
			Object instance = cls.newInstance();
			System.out.println("无参构造创建对象:"+instance);//默认调用类中的toString()方法
			
			/**
			 * 通过有参构造方法创建对象
			 */
			Constructor<?> con = cls.getConstructor(String.class,Integer.class,String.class);//这里的参数是class类型的可变参数
			Object o2 = con.newInstance("有参构造创建对象:"+"张三",100,"男");
			System.out.println(o2);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

class Person{
	private String name;
	private Integer age;
	private String sex;
	public Person() {}
	public Person(String name, Integer age, String sex) {
		super();
		this.name = name;
		this.age = age;
		this.sex = sex;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]";
	}
}

3、调用类中的普通方法

1、获得class对象

//获得类对象
Class<?> cls = Class.forName("reflect.Person");

2、获得方法
(1)getMethods()方法获得class对象对应的类中的所有的非私有方法,包括继承过来的方法

Method[] methods = cls.getMethods();
for(Method m : methods) {
	//直接输出m的话会输出每个方法的具体信息,包括修饰权限和返回值类型
	//getName()获得方法的名字
	System.out.println(m.getName());
}

输出结果
在这里插入图片描述
(2)getName(methodName,paraType)根据方法名获得方法(有多个重载方法使用),第一个参数是方法名,第二个参数是方法里面的参数类型的class对象,是可变参数,方法没有参数不用传第二个参数

//获得有参构造函数
Constructor<?> con = cls.getConstructor(String.class,Integer.class,String.class);
//根据有参构造创建对象
Object o = con.newInstance("李四",23,"女");

获得person类中的getName()方法

Method getName = cls.getMethod("getName");

调用类中的方法使用invoke()方法,调用之前需要先创建对象

Object s = getName.invoke(o);//得到方法的返回值
System.out.println(s);

输出

李四

获得person类中的setName()方法

Method setName = cls.getMethod("setName",String.class);
Object s2 = setName.invoke(o, "王五");//得到方法的返回值
System.out.println(s2);

输出:因为set方法没有返回值,所以输出为null

null

完整代码

public class ReflectDemo03 {
	public static void main(String[] args) {
		try {
			//获得类对象
			Class<?> cls = Class.forName("reflect.Person");
			//getMethods()获得类对象对应的类中的所有的方法
			Method[] methods = cls.getMethods();
			for(Method m : methods) {
				//直接输出m的话会输出每个方法的具体信息,包括修饰权限和返回值类型
				//getName()获得方法的名字
				System.out.println("具体信息:"+m);
				System.out.println("方法名:"+m.getName());
			}
			
			/**
			 * getName(methodName,paraType)根据方法名获得方法(有多个重载方法使用),
			 * 第一个参数是方法名,第二个参数是方法里面的参数类型的class对象,是可变参数
			 * 方法没有参数不用传第二个参数
			 */
			Constructor<?> con = cls.getConstructor(String.class,Integer.class,String.class);
			Object o = con.newInstance("李四",23,"女");
			//获得方法
			Method getName = cls.getMethod("getName");
			//调用方法使用invoke()方法,调用之前需要先创建对象
			Object s = getName.invoke(o);//得到方法的返回值
			System.out.println(s);
			
			Method setName = cls.getMethod("setName",String.class);
			Object s2 = setName.invoke(o, "王五");//得到方法的返回值
			System.out.println(s2);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

4、将类中的私有方法设置为可访问

先创建一个测试类

class Test{
	private void test1() {
		System.out.println("私有方法1");
	}
	
	public void test2() {
		System.out.println("公有方法1");
	}
}

获得class对象

Class<?> cls = Test.class;

getDeclaredMethods()可以获得类中所有定义的方法,不包含继承过来的方法

Method[] methods2 = cls.getDeclaredMethods();
	for(Method m:methods2) {
		System.out.println(m.getName());
	}

输出:

test1
test2

根据方法名字获得类中的私有方法,然后创建对象,使用setAccessible(boolean b)方法,参数为true即可把私有方法设置方法为可访问

Method method = cls.getDeclaredMethod("test1");

//获得根据无参构造创建的类对象
Object o = cls.newInstance();
			
//setAccessible(boolean b)参数为true即可把私有方法设置方法为可访问
method.setAccessible(true);
method.invoke(o);

完整代码

public class ReflectDemo03 {
	public static void main(String[] args) {
		try {
			//获得类对象
			Class<?> cls = Class.forName("reflect.Person");
			//getMethods()获得类对象对应的类中的所有的方法
			Method[] methods = cls.getMethods();
			for(Method m : methods) {
				//直接输出m的话会输出每个方法的具体信息,包括修饰权限和返回值类型
				//getName()获得方法的名字
				System.out.println("具体信息:"+m);
				System.out.println("方法名:"+m.getName());
			}
			
			/**
			 * getName(methodName,paraType)根据方法名获得方法(有多个重载方法使用),
			 * 第一个参数是方法名,第二个参数是方法里面的参数类型的class对象,是可变参数
			 * 方法没有参数不用传第二个参数
			 */
			Constructor<?> con = cls.getConstructor(String.class,Integer.class,String.class);
			Object o = con.newInstance("李四",23,"女");
			//获得方法
			Method getName = cls.getMethod("getName");
			//调用方法使用invoke()方法,调用之前需要先创建对象
			Object s = getName.invoke(o);//得到方法的返回值
			System.out.println(s);
			
			Method setName = cls.getMethod("setName",String.class);
			Object s2 = setName.invoke(o, "王五");//得到方法的返回值
			System.out.println(s2);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java反射可以让我们在运行时获取和操作类的信息,包括类的属性、方法、构造函数等。下面是一个使用Java反射的简单案例: 假设我们有一个类Person: ```java public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public void sayHello() { System.out.println("Hello, my name is " + name + ", I am " + age + " years old."); } } ``` 现在,我们可以使用反射来获取和调用Person类的构造函数和方法: ```java import java.lang.reflect.Constructor; import java.lang.reflect.Method; public class ReflectionExample { public static void main(String[] args) throws Exception { // 获取Person类的Class对象 Class<Person> personClass = Person.class; // 获取Person类的构造函数 Constructor<Person> constructor = personClass.getConstructor(String.class, int.class); // 使用构造函数创建Person对象 Person person = constructor.newInstance("Tom", 20); // 获取Person类的sayHello方法 Method sayHelloMethod = personClass.getMethod("sayHello"); // 调用sayHello方法 sayHelloMethod.invoke(person); } } ``` 以上代码中,我们首先通过`Person.class`获取了Person类的Class对象,然后使用`getConstructor`方法获取了Person类的构造函数,并使用构造函数创建了一个Person对象。接着,我们使用`getMethod`方法获取了Person类的`sayHello`方法,并使用`invoke`方法调用了该方法。最终,我们输出了`Hello, my name is Tom, I am 20 years old.`。 这只是一个简单的反射案例,实际上Java反射还可以做很多其他的事情,比如动态代理、注解处理等等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值