网站首页> 文章专栏> java与其它编程不同的特色---反射
java与其它编程不同的特色---反射
路人王 天津 2020-05-09 117 0 0

一、反射概念

1.1 对象的反向操作

反射指的是对象的反向操作,根据对象取得对象的来源信息,关注的是对象后面的组成,类,成员,构造等等

  • Class是整个类的概念,而这个类的对象的生产模式一共有三种
  • 1.Object的getClass()方法,返回的class对象
  • 2.类.class,根据具体的类来取得Class类的实例化对象
  • 3.forName()方法
  • 正常正向:导包-->实例化对象

1.2 反射代码:

public class ReflectDemo {

	public static void main(String[] args) throws ClassNotFoundException {
		// 1.第一种实例化
		Date date = new Date();
		// class java.util.Date
		System.out.println(date.getClass());
		
		// 2.第二种实例化
		Class<?> date2 = Date.class;
		System.out.println(date2.getName());
		
		// 3.第三种实例化,不需要导包 拿到操作权限
		Class<?> date3 = Class.forName("java.util.Date");
		System.out.println(date3.getName());

	}

}

二、反射的操作

2.1 反射取得父类信息

/**  
 * @author captain  
 * @date 2019年5月2日  
 * 在定义java类的时候,一定要保留一个无参构造方法
 * 2.1.取得父类信息
 */

class Person2 {
	private int age;
	private String name;
	public Person2() {}
	
	public Person2(String name, int age) {
		this.name = name;
		this.age = age;
	}

	@Override
	public String toString() {
		return "Person2 [age=" + age + ", name=" + name + "]";
	}
}

public class ReflectionOperate2 {

	public static void main(String[] args) throws Exception{
		Class<?> cls = Person2.class;
		
		// 打印构造方法 取得指定参数类型的构造方法
		Constructor<?> conts[]  =  cls.getConstructors();
		//Constructor<?> conts  =  cls.getConstructor(String.class, int.class);
		
		for(int x = 0; x < conts.length; x++) {
			System.out.println(conts[x]);
		}
		
		// 通过反射调用构造方法,只能调用无参构造方法
		System.out.println(cls.newInstance());
	}

}

2.2 反射取得普通方法

  • 在定义java类的时候,一定要保留一个无参构造方法
  • 没有反射,就没有框架,java与其他语言的特别之处,最亮之处
  • 取得普通方法 :一定会使用到,解决重复编码 Method的invoke()方法
  • 取得一个类的全部方法getMethods() 返回一个method的对象
  • 取得指定方法getMethod()
  • 所有的方法再有了实例化对象之后才可以使用。有了反射之后,来实现。
  • 通过反射来调用setter getter
class Person3 {
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
}

public class ReflectionOperate3 {

	public static void main(String[] args) throws Exception{
		
		Class<?> cls = Class.forName("com.wang.aliyun.reflect.Person3");
		
		// 拿到所有的方法
		Method met[] = cls.getMethods();
		for(int x = 0;x <met.length;x ++) {
			System.out.println(met[x]);
		}
		
		// 任何情况下调用类中的普通方法,必须要有实例化对象
		String value = "WANG";
		Object obj = cls.newInstance();
		Method setMethod = cls.getMethod("setName", String.class);
		// 相当于Person.setName()
		setMethod.invoke(obj, value);
		
		// 输出的话 相当于Person.getName()
		Method getMethod = cls.getMethod("getName");
		Object ret = getMethod.invoke(obj);
		System.out.println(ret);
	}

}

2.3 反射取得成员

  • 1.取得成员调用
  • 类对象的属性,一定会在实例化之后进行空间的分配,必须保证要有实例化对象 通过反射的newInstance【Object类型】
  • 否则属性无法开辟空间
  • 2.两组取得属性的方法
  • 取得父类中所有的属性 getFields()
  • 取得指定类型的属性 getField()
  • getDeclaredFields 本类
  • getDeclaredField 本类
  • 3.开发之中,不会适用如下方法
  • 开发使用getter setter方法
class Person4 {
	private String name; // 属性 	
}

class Student extends Person4{
	private String school;
}


public class ReflectionOperate4 {
	public static void main(String[] args) throws Exception{
		
		Class<?> cls = Class.forName("com.wang.aliyun.reflect.Person");
		{
			// 1.普通代码块 取得类全部属性
			Field fields[] = cls.getFields();
			for(int x = 0; x < fields.length; x ++) {
				System.out.println(fields[x]);
			}
		}
		
		System.out.println("=================================");
		
		{
			// 2.普通代码块 取得类全部属性
			Field fields[] = cls.getDeclaredFields();
			for(int x = 0; x < fields.length; x ++) {
				System.out.println(fields[x]);
			}
		}
		
		System.out.println("=================================");
		
		// 3.指定名字
		Object obj = cls.newInstance();
		Field nameField = cls.getDeclaredField("name");
		System.out.println(nameField.getType().getName()); // java.lang.String
		System.out.println(nameField.getType().getSimpleName()); // String 
		
		// 取消封装,private的权限不起作用了
		nameField.setAccessible(true);
		nameField.set(obj, "迪丽热巴");
		System.out.println(nameField.get(obj)); //没有setAccessible(true);private权限会报错
	}

}

java  

评论

评论  分享  打赏