java基础---反射

1 反射

1.1 反射介绍

  • 什么是反射:
    • 反射可以把它称为动态语言,允许程序在运行期间借助于反射API可以获取类的完整信息。
  • 功能:
    • 在运行期间可以获取对象的类型
    • 可以在运行期间构造对象
    • 可以在运行期间可以获取类的完整结构
    • 可以在运行期获取指定类的属性和方法及构造器。
  • 反射API:
    • java.lang.Class 可以获取运行时类的实例
    • java.lang.reflect. Field 属性(成员变量)
    • java.lang.reflect. Method 方法
    • java.lang.reflect. Constructor 构造器
public class TestReflect {
	//使用反射
	@Test
	public void test2() throws Exception {
		//运行时类的对象(实例)
		Class cla = Student.class;
		Student stu = (Student)cla.newInstance();  //创建类的对象 
		System.out.println(stu);
		//属性
		Field name = cla.getField("name");  //只能获取public		
		name.set(stu, "张三");
		System.out.println(stu);
		//方法
		Method m = cla.getMethod("info",String.class,int.class);  //只能获取public
		m.invoke(stu,"张三", 20 );  //调用  
		
	}
	
	//没有用反射
	@Test
	public void test1() {
		Student stu = new Student("",10);
		System.out.println(stu);
		stu.name="张三";
		System.out.println(stu.name);
		
		stu.setSex("男");
		stu.info("张三", 20);
	}
}

1.2 理解Class类创建Class类的实例

  • Class类:

    表示正在运行的Java应用程序中的类和接口

  • 原理:

    创建一个java类,javac.exe编译.class文件(字节码),此时使java.exe将.class加载(jvm类加载器)到内存中,在内存中的.class文件就是一运行时的类,也可以称为Class类的实例。

  • 创建Class类的实例:

    • 可以通过运行时类.class来创建. 如:Class c = Student.class; String.class;
    • 可以通过类的对象.getClass() 如:Student s = new Student(); Class c = s.getClass();
    • 可以通过Class类中的静态方法forName(“”); 如:Class c=Class.forName(“类的全路径”);
    • 类加载器获取ClassLoader cl = stu.getClass().getClassLoader();

​ Class c = cl.loadClass(“com.aura.java2.Student”);

//获取运行时类的实例
   @Test
   public void test3() throws Exception {
   	//1
   	Class c1 = Student.class;		
   	//2
   	//Student stu = new Student();
   	Student stu = (Student)c1.newInstance();
   	Class c2 = stu.getClass();
   	//3静态方法
   	Class c3 = Class.forName("com.aura.java2.Student");
   	
   	
   	System.out.println(c1==c2);   //true
   	System.out.println(c1==c3);    //true
   }

1.3 根据Class类的实例获取类的完整结构

  • 属性

    //属性
    	@Test
    	public void test1() {
    		//获取Class类的实例
    		Class clazz = Student.class;
    		Field[] fields = clazz.getFields();  //只能public自身和父类
    		for (Field field : fields) {
    			System.out.println(field.getName());
    		}
    		System.out.println("===============================");
    		Field[] declaredFields = clazz.getDeclaredFields();//所有自己但不能获取父类
    		for (Field f : declaredFields) {
    			//获取修饰符
    			int m = f.getModifiers();
    			String str = Modifier.toString(m);
    			System.out.print(str+"  ");
    			//类型
    			Class type = f.getType();
    			System.out.print(type.getName()+"  ");
    			//名称
    			System.out.println(f.getName());
    		}
    	}
    
  • 方法

    //方法
    	@Test
    	public void test2() throws Exception {
    		Class clazz = Class.forName("com.aura.java2.Student");
    		Method[] methods = clazz.getMethods();   //自身和父类public的方法
    		for (Method m : methods) {
    			System.out.println(m);
    		}
    		System.out.println("==============================");
    		Method[] methods2 = clazz.getDeclaredMethods();  //自身的所有方法
    		for (Method m : methods2) {			
    			//修饰符
    			int m1 = m.getModifiers();
    			String str = Modifier.toString(m1);
    			System.out.print(str+"  ");
    			//返回值类型
    			Class rt = m.getReturnType();
    			System.out.print(rt.getName()+"  ");
    			//方法名
    			System.out.print(m.getName());  
    			Class[] parameterTypes = m.getParameterTypes();
    			Parameter[] parameters = m.getParameters();
    			System.out.print("(");
    			for (int i=0;i<parameterTypes.length;i++) {
    				System.out.print(parameterTypes[i].getName()+"  "+parameters[i].getName());
    			}
    			System.out.print(")");
    			//异常
    			Class[] ex = m.getExceptionTypes();
    			if(ex.length!=0) {
    				System.out.print("throws");
    			}
    			//输出异常类型 
    			System.out.println();
    			System.out.println();
    			
    		}
    	}
    
  • 构造器

    //方法
    	@Test
    	public void test3() throws Exception {
    		Class clazz = Class.forName("com.aura.java2.Student");
    		Constructor[] c1 = clazz.getConstructors();  //本类公有构造器
    		for (Constructor constructor : c1) {
    			System.out.println(constructor);
    		}
    		System.out.println("====================================");
    		Constructor[] c2 = clazz.getDeclaredConstructors();  //本类的所有构造器
    		for (Constructor constructor : c2) {
    			System.out.println(constructor);
    			
    		}
    		
    	}
    
  • 父类

    getSuperClass() //只有一个父类

  • 注解

    getAnnotations() //所有注解

  • 接口

    getInterfaces(); //接口有多个

    @Test
    		public void test4() throws Exception {
    			Class clazz = Class.forName("com.aura.java2.Student");
    			clazz.getSuperclass();  //父类
    			
    			clazz.getAnnotations();  //注解 
    			clazz.getDeclaredAnnotations();
    			
    			clazz.getInterfaces();   //接口
    			
    		}
    

1.4 通过反射获取指定类属性,方法,构造器

  • 属性

    //设置指定的属性
    	@Test
    	public void test1() throws Exception {
    		//创建Class类的实例
    		Class clazz = Student.class;
    		//创建Student类对象
    		Student stu =(Student)clazz.newInstance();
    		Field name = clazz.getField("name");  //public
    		name.set(stu, "小明");
    		System.out.println(stu);  //姓名
    		
    		Field age = clazz.getDeclaredField("age");  //所有的
    		
    		age.set(stu, 23);
    		System.out.println(stu);  //姓名 年龄 
    		//属性
    		Field sex = clazz.getDeclaredField("sex");  //所有的private
    		sex.setAccessible(true);  //设置 权限 private
    		sex.set(stu, "男");
    		System.out.println(stu);  //姓名年龄  性别	
    		
    	}
    
  • 方法

    //设置或调用指定的方法
    	@Test
    	public void test2() throws Exception {
    		//创建Class类的实例
    		Class clazz = Student.class;
    		//创建Student类对象
    		Student stu =(Student)clazz.newInstance();  //直接类的无参构造器
    		//获取指定的方法
    		Method m = clazz.getMethod("toString");   //public
    		Object result = m.invoke(stu);
    		System.out.println(result);
    		
    		Method m1 =clazz.getDeclaredMethod("show", String.class,int.class); //参数的类型
    		m1.setAccessible(true);
    		m1.invoke(stu, "小刘",22);  //实参
    		
    	}
    
  • 构造器

    //设置或调用指定的构造器 
    	@Test
    	public void test3() throws Exception {
    		//创建Class类的实例
    		Class clazz = Student.class;
    		//创建Student类对象(调用无参构造 )1
    		Student stu =(Student)clazz.newInstance();  //直接类的无参构造器
    		System.out.println(stu);
    		//调用指定的构造器
    		//无参 2
    		Constructor c1 = clazz.getConstructor();
    		Student obj = (Student)c1.newInstance();
    		System.out.println(obj);
    		System.out.println("==================================");
    		//有参
    		Constructor c2 = clazz.getConstructor(String.class,int.class);
    		Student obj2 = (Student)c2.newInstance("李四",25);
    		System.out.println(obj2);
    		//私有权限构造 器
    		Constructor c3 = clazz.getDeclaredConstructor(String.class,int.class,String.class);
    		c3.setAccessible(true);
    		Student obj3 = (Student)c3.newInstance("赵六",28,"男");
    		System.out.println(obj3);
    	}
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bromide-0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值