java类型信息与反射机制

Class对象
Class对象就是用来创建类的所有“常规“对象的,每一个类都有一个Class对象,每当编译了一个新类,就会产生一个Class对象,保存在同名的.class文件中。

Class.forName(" ");
这个方法是Class类(所有Class对象都属于这个类)的一个static成员,类名需要全包名,返回一个Class对象的引用。

一些常用的方法
在这里插入图片描述
在这里插入图片描述
Class的newInstance()方法是实现虚拟构造器的一种途径,会返回一个新的Object实例。

类字面常量
java提供了另一种方法来生成对Class对象的引用:类名.class,这样不仅简单,而且在编译时就会受到检查。

泛化的Class引用

Class intclass=int.class;
Class<Integer> gIntClass=int.class;
gIntClass=Integer.class;
intclass=double.class;
gIntClass=double.class//有错误

泛型类的引用只能赋值为其声明的类型,但是普通的类引用可以重新赋值为任何其他的Class对象。

通配符
Class<?> 优于平凡的Class,好处是表示你碰巧或者由于疏忽,而使用了一个非具体类引用,你就是选择了非具体版本。

Class<? extends 类型>被限定为此类型或他的子类。
获取属性

//公共属性
			Field[] fields = perClazz.getFields() ;
			for(Field field:fields) {
				System.out.println(field);
			}
			System.out.println("====");
			//所有属性  (属性的 :公共属性\所有属性的区别 同“方法”)
			Field[] declaredFields = perClazz.getDeclaredFields() ;
			for(Field declaredField:declaredFields) {
				System.out.println(declaredField);
			}

获取方法

try {
			perClazz =  Class.forName("reflect.Person") ;
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		//获取所有的 公共的方法(1.本类 以及 父类、接口中的所有方法  2.符合访问修饰符规律)
		  Method[] methods = perClazz.getMethods();
		  for(Method method:methods) {
			  System.out.println(method);
		  }
		  System.out.println("==========");
		  //获取当前类的所有方法(1.只能是当前类   2.忽略访问修饰符限制)
		  Method[] declaredMethods = perClazz.getDeclaredMethods();
		  for(Method declaredMethod:declaredMethods) {
			  System.out.println(declaredMethod);
		  }

获取接口

Class<?>[] interfaces = perClazz.getInterfaces() ;
		for(Class<?> inter:interfaces) {
			System.out.println(inter);
		}

获取父类

Class<?> superclass = perClazz.getSuperclass() ;
			System.out.println(superclass);

获取所有构造方法

Constructor<?>[] constructors = perClazz.getConstructors() ;
			for(Constructor<?> constructor:constructors) {
				System.out.println(constructor);
				
			}

获取一个对象并操作

public static void demo01() throws InstantiationException, IllegalAccessException {
			Class<?> perClazz =  null ; 
			try {
				perClazz =  Class.forName("reflect.Person") ;
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
			Person per = (Person)perClazz.newInstance() ;
			per.setName("zs");//person中已有的方法
			per.setAge(23);
			System.out.println(  per.getName()+","+per.getAge());
	}

操作属性
Field/Method/Constructor.setAccessible(true)方法将访问权限忽略

Person per = (Person)perClazz.newInstance() ;
		Field idField = perClazz.getDeclaredField(  "id");//根据名字找属性
		//访问的是private修饰的id,但是private是私有
		//修改属性的访问权限  使用反射时,如果 因为访问修饰符限制造成异常,可以通过  Field/Method/Constructor.setAccessible(true)
		idField.setAccessible(true);
		idField.set(per, 1);   //per.setId(1);
		System.out.println( per.getId() );

操作方法
第一个参数是方法名买第二个参数是获取方法的参数类型

Method method = perClazz.getDeclaredMethod("privateMethod", null) ;
		method.setAccessible(true);
		method.invoke(per,null )  ;//方法的调用:invoke()
		//per.say(xxx);
		//
		Method method2 = perClazz.getDeclaredMethod("privateMethod2", String.class) ;
		method2.setAccessible(true);
		method2.invoke(per, "zs") ;

操作构造方法

//获取指定的构造方法  
		//在反射中,根据类型 获取方法时:基本类型(int、char...)和包装类(Integer,Character)是不同的类型
		Constructor<?> constructor = perClazz.getConstructor(Integer.class) ;
		System.out.println(constructor);
		//
		Constructor<?> constructor2 = perClazz.getDeclaredConstructor(String.class) ;
		System.out.println(constructor2);
		//Person per = new Person() ;
		//
		//
		//根据获取的private构造方法,获取对象实例
		constructor2.setAccessible(true);
		Person per3 = (Person)constructor2.newInstance("zs") ;
		System.out.println("per3"+per3);
		//
		Person per4 = (Person)constructor.newInstance(23) ;//因为constructor是 有参构造方法(Integer),因此需要传入一个Integer值
		System.out.println(per4);
		//
		Constructor<?> constructor3 = perClazz.getConstructor() ;
		Person per5 = (Person)constructor3.newInstance( ) ;//因为constructor3是 无参构造方法,因此不需要传值
		//
		System.out.println(per5);
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值