JAVA 反射方法再总结

本文详细介绍了通过Java反射API获取字节码的不同方式,包括Class.forName、类名.class和对象.getClass,并对比了它们的优缺点。此外,还讲解了如何通过反射创建对象,获取构造器、字段和方法,以及其实例应用。
摘要由CSDN通过智能技术生成

目录

一.通过反射获取字节码有三种办法

1.Class.forName(类全限定名)

2.类名.class

3.obj.getClass

4.三种方法的优缺点分析

二.通过反射创建对象有两种办法

1.直接使用获取的字节码class创建对象

2.利用无参构造器对象创建对象

三.获取一个类中的构造器的方法

1.获取所有公有属性的构造器的清单

2.获取所有属性的构造器的清单

3.获取单个构造器。

四.字段(属性)

1.获取单个字段对象 (公有的)

2..获取单个字段对象 (公有+非公有的)

3.设置 "某个对象" 的 "某个字段" 的值(什么字段.set( 哪个对象, 什么值 ))

4.获取 "某个对象" 的 "某个字段" 的值(bject 值 = 什么字段.get( 哪个对象 ))

5.获取静态变量 不用传入对象

五.方法

1.获取所有公有的方法(列表)

2.获取所有已声明的方法(列表)

3.获取公有的方法(单个)

4.获取已声明的方法(单个)

5.使用方法

6.代码



反射的一些方法再总结

一.通过反射获取字节码有三种办法

1.Class.forName(类全限定名)

Class<?> class1 = Class.forName("com.gongsi.cn.test1.User"); ​

System.out.println(class1);

2.类名.class

Class class2 = User.class; System.out.println(class2);

3.obj.getClass

User user = new User(); Class class3 = user.getClass(); System.out.println(class3);

4.三种方法的优缺点分析

二.通过反射创建对象有两种办法

1.直接使用获取的字节码class创建对象

(调用无参构造器来初始化)

Object object = class1.newInstance(); 
System.out.println(object);

(调用有参构造器来初始化)

cons3.setAccessible(true);// 打开访问通道, 设置可访问。
cons3.newInstance(12);
cons4.newInstance("dailyrs", 12, 50);

2.利用无参构造器对象创建对象

Constructor<?> c = class1.getConstructor();
Object object2 = c.newInstance(); 
System.out.println(object2);

三.获取一个类中的构造器的方法

1.获取所有公有属性的构造器的清单

Constructor<?>[] cons1 = class1.getConstructors();

System.out.println("+-------------(仅有公有权限)-----------------+");

for (Constructor<?> constructor : cons1) {

System.out.println(constructor);

}

2.获取所有属性的构造器的清单

Constructor<?>[] cons2 = class1.getDeclaredConstructors();

System.out.println("+-------------(所有权限)-----------------+");

for (Constructor<?> constructor : cons2) {

System.out.println(constructor);

}

3.获取单个构造器。

System.out.println("-------获取单个构造器---------");

Constructor<?> cons3 = class1.getDeclaredConstructor(int.class);

System.out.println(cons3);

Constructor<?> cons4 = class1.getDeclaredConstructor(String.class, int.class, float.class); System.out.println(cons4);

四.字段(属性)

1.获取单个字段对象 (公有的)

clz.getField( 字段名 );

2..获取单个字段对象 (公有+非公有的)

Field f3 = class1.getDeclaredField("age");

Field f4 = class1.getDeclaredField("weight");

3.设置 "某个对象" 的 "某个字段" 的值(什么字段.set( 哪个对象, 什么值 ))

f3.setAccessible(true); f3.set(user1, 18);

4.获取 "某个对象" 的 "某个字段" 的值(bject 值 = 什么字段.get( 哪个对象 ))

Object object4 = f3.get(user1);

5.获取静态变量 不用传入对象

Field f5 = class1.getDeclaredField("address");

f5.set(null, "广西玉林");

Object object5 = f5.get(null);

System.out.println(object5);

五.方法

1.获取所有公有的方法(列表)

clazz.getMethods();

2.获取所有已声明的方法(列表)

[clazz.getDecalaredMethods();

3.获取公有的方法(单个)

clazz.getMethod(参数类型列表);

4.获取已声明的方法(单个)

 clazz.getDecalaredMethod(参数类型列表);

5.使用方法

method.invoke( 值列表 )

一些传参方法:

{A}散值传参法

  getDeclaredMethod(方法名, 类型1,类型2,..);
  method.invoke( 对象,值1,值2... );

{B}数组传参法

getDeclaredMethod(方法名, 1个数组 存储类型);

method.invoke( 对象,1个obj数组存储数值  );

6.代码

package com.gongsi.cn.test1;

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

public class testMain {
	public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {

		/*
		 * [1] clazz.getMethods(); //获取所有公有的方法(列表) 
		 * [2] clazz.getDecalaredMethods();//获取所有已声明的方法(列表)
		 * [3] clazz.getMethod(参数类型列表); //获取公有的方法(单个) [4]
		 * clazz.getDecalaredMethod(参数类型列表); //获取已声明的方法(单个)
		 * 
		 * [5] method.invoke( 值列表 );
		 */

		//1.获取字节码对象。
		Class clazz = User.class;
		//2.反射来创建对象 (主调对象)。
		Object obj = clazz.newInstance();
		//3.获取所有已声明的方法(单个)
		Method mtd1 = clazz.getDeclaredMethod("eat", String.class);
		Method mtd2 = clazz.getDeclaredMethod("eat", String.class,int.class);
		Method mtd3 = clazz.getDeclaredMethod("haveLunch", String[].class);
		//4.打开访问权限。。
		mtd1.setAccessible( true );
		mtd2.setAccessible( true );
		mtd3.setAccessible( true );
		//5.调用方法
		//格式: mtd.invoke(主调对象, 值列表);
		//如果,方法没有设置返回值 void, ret=null
		//如果,方法有返回值,但是返回是 null, ret=null
		
		//一些传参方法
		//{A}散值传参法。。
		//getDeclaredMethod(方法名, 类型1,类型2,..);
		//method.invoke( 对象,值1,值2... );
		Object ret = mtd1.invoke(obj, "吃很多很多好吃的");
		Object ret2 = mtd2.invoke(obj, "吃很多很多好吃的",1);
		String[] s= {"赞比","啵比","小王","肖肖"};
		Object object=s;//将数组转化为一串字符  //为了将它转为: 散值传参法
		Object ret3 = mtd3.invoke(obj,object );
		
		//{B}数组传参法。。
		//getDeclaredMethod(方法名, 1个数组 存储类型);
		//method.invoke( 对象,1个obj数组存储数值  );
		Class[] types = {String.class, int.class};//把类型封装在一个数组里
		Method mtd4 = clazz.getDeclaredMethod(
				"eat", types );
		Object[] vals = {"鸡", 10};//把要传的值封装在一个数组里
		mtd4.invoke(obj, vals);

	}
}
package com.gongsi.cn.test1;

public class User {
	private void eat(String something){
		System.out.println("我正在吃"+ something);
	}
	public void eat(String something, int time){
		System.out.printf(
				"我要吃%s, %d小时", something, time );
	}
	public void haveLunch(String[] users){
		System.out.printf("我要他们吃饭..\n");
		for (String u : users) {
			System.out.printf("{%s}\n", u);
		}
	}
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值