java 基础加强 反射 day02

使用构造器创建对象
Class claz = User.class;
//获取无参构造
Constructor constructor = claz.getConstructor();
//创建对象
User newInstance = (User)constructor.newInstance();//打印出无参
//获取String name构造
Constructor constructor2 = claz.getConstructor(String.class);
//创建对象
User newInstance2 = (User)constructor2.newInstance("小黑");//打印出name=小黑
//获取String name,int age构造 注意 private需要用getDeclaredConstructor
Constructor constructor3 = claz.getDeclaredConstructor(String.class,int.class);
//创建对象(注意private构造不能直接使用newInstance)会报错Class com.io.aa can not access a member of                 class com.io.User with modifiers "private"
constructor3.setAccessible(true);//这句设置表示直接可以访问private修饰的构造器
User newInstance3 = (User)constructor3.newInstance("小黑",2);//打印出name=小黑age=2

//注意如果某个类中构造器是public修饰且无参可以用Class对象的newInstance()方法直接创建对象

User newInstance4 = (User)claz.newInstance();

User类
class User{
	public User(){
		System.out.println("无参");
	}
	public User(String name){
		System.out.println("name="+name);
	}
	private User(String name,int age){
		System.out.println("name="+name+"age="+age);
	}
	
}
获取类中的方法                

                Class claz = User.class;

Method[] methods = claz.getMethods();
//这里打印出如下方法 getMethods() 方法会获取所有该类以及父类的 公共 (public修饰的)方法
// public void com.ref.User.xx1(java.lang.String)
// public void com.ref.User.xx1()
// public final void java.lang.Object.wait() throws java.lang.InterruptedException
// public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
// public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
// public boolean java.lang.Object.equals(java.lang.Object)
// public java.lang.String java.lang.Object.toString()
// public native int java.lang.Object.hashCode()
// public final native java.lang.Class java.lang.Object.getClass()
// public final native void java.lang.Object.notify()
// public final native void java.lang.Object.notifyAll()
for (Method method : methods) {
// System.out.println(method);
}
//这里打印出如下方法 getDeclaredMethods() 方法会获取所有该类所有方法(忽略修饰符)
Method[] declaredMethods = claz.getDeclaredMethods();
for (Method method : declaredMethods) {
// System.out.println(method);
}
//获取单个方法   参数:方法名,参数类型的数组(无参可以不传);
Method method = claz.getMethod("xx1");
System.out.println(method);//public void com.ref.User.xx1()
Method method2 = claz.getMethod("xx1",String.class);
System.out.println(method2);//public void com.ref.User.xx1(java.lang.String)
//报错,因为getMethod方法无法获取private、protcted、default修饰的方法
// Method method3 = claz.getMethod("xx2",String.class,int.class);
// System.out.println(method3);//java.lang.NoSuchMethodException

//修改为getDeclaredMethod();
Method method3 = claz.getDeclaredMethod("xx2",String.class,int.class);

System.out.println(method3);//protected void com.ref.User.xx2(java.lang.String,int)

User类
class User{
	public void xx1(){
		
	}
	public void xx1(String name){
		
	}
	protected void xx2(String name,int age){
		
	}
}
方法的调用

                //使用构造器创建对象
Class claz = User.class;
//获取无参构造
Constructor constructor = claz.getConstructor();
User newInstance =(User) constructor.newInstance();
//调用无参的xx1()方法
Method method = claz.getMethod("xx1");
method.invoke(newInstance);
//调用有参的xx3(String name)方法
method = claz.getMethod("xx3",String.class);
method.invoke(newInstance,"小米");
//调用私有的有参的xx3(int age)方法     getDeclaredMethod
method = claz.getDeclaredMethod("xx3",int.class);
method.setAccessible(true);
int age = (int)method.invoke(newInstance,123333);
System.out.println(age);

    User类

class User{
	public void xx1(){
		System.out.println("123");
	}
	public void xx3(String name){
		System.out.println(name);
	}
	private int xx3(int age){
		System.out.println(age);
		return age;
	}
	public User(){}
}
用Object类型的对象去调用真实类型的对象的方法
Object obj = new Date();
Method method = obj.getClass().getMethod("toLocaleString");
Object invoke = method.invoke(obj);

System.out.println(invoke);

调用static方法一样可以用对象调用(但是底层还是用类名去调用的)所以invoke的第一个参数可以传一个null或者传任何对象(这个对象最后并不会被使用)

                Class claz= User.class;
Method method = claz.getMethod("xx3", String.class);

method.invoke(null, "小米");

                method.invoke(new Object(), "小米");

带数组参数的方法的执行
     Class claz= User.class;
//带基本类型数组参数的执行方法(不能使用可变参数来传递参数,会被认为是多个参数)
Method method = claz.getMethod("xx3", int[].class);
// method.invoke(null,1,2);//报错wrong number of arguments
method.invoke(null,new int[]{1,2});
method.invoke(null,new Object[]{new int[]{1,2}});
//带引用类型数组参数的执行方法(不能使用可变参数来传递参数,会被认为是多个参数)
method = claz.getMethod("xx3", String[].class);
args = new String[]{"1","2"};
//当数组中是引用类型时会被自动拆解为一个个的参数
//因为invoke(Object obj, Object... args)方法接收的第二个参数类型本来就是object数组
//String数组也是object数组  (int数组也是,但是基本类型就不会被解析)
//所以此时的第二个参数应该为new Object[]{args}相当于一个二维数组索引为1 的 值是一个数组


method.invoke(null, new Object[]{args});
// method.invoke(null, args);//报错wrong number of arguments

// 推荐所有的invoke方法第二个参数都传一个Object数组用此Object数组来装任何类型参数

执行带泛型参数的方法
                Method method = claz.getDeclaredMethod("xx1",Object[].class);
method.setAccessible(true);
method.invoke(claz.newInstance(), new Object[]{new Object[]{"1",2}});

                //泛型参数本质就是object直接当成obj来操作就可以了

        User类

class User<E>{
	private void xx1(E... a) {
		for (E t : a) {
			System.out.println(t);
		}	
	}
	public static void xx3(int[] name){
		System.out.println(Arrays.toString(name));
	}
	public static void xx3(String[] name){
		System.out.println(Arrays.toString(name));
	}
	public User(){}
}
操作字段的四个方法

FieldgetDeclaredField(String name)
返回一个 Field对象,它反映此表示的类或接口的指定已声明字段 对象。
Field[]getDeclaredFields()
返回的数组 Field对象反映此表示的类或接口声明的所有字段 对象。  
FieldgetField(String name)
返回一个 Field对象,它反映此表示的类或接口的指定公共成员字段 对象。
Field[]getFields()
返回包含一个数组 Field对象反射由此表示的类或接口的所有可访问的公共字段 对象。 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值