자바 기초 26 ~ 반사

프로그래밍을 좋아하는 당신처럼!
SpringBoot 실습 과정 배우기 https://edu.csdn.net/course/detail/31433
SpringCloud 입문 과정 배우기 https://edu.csdn.net/course/detail/31451


머리말

리플렉션은 자바의 중요한 기술이며 리플렉션을 마스터 한 후 다양한 자바 프레임 워크의 기본 원칙을 마스터하는 것이 도움이됩니다.

반사 메커니즘이란?

Reflection은 프로그램이 실행 중일 때 클래스의 메서드, 속성 및 구성 메서드와 같은 내부 멤버의 정보를 동적으로 가져 와서 클래스의 개체를 동적으로 만들고 클래스의 속성과 메서드를 호출하는 것입니다.

반사는 무엇을 할 수 있습니까?

프로그램의 유연성을 크게 향상시켜 매우 다양한 코드를 작성할 수 있습니다.
주류 엔터프라이즈 급 프레임 워크는 모두 Spring, Hibernate, MyBatis, Shiro 등과 같은 리플렉션 메커니즘을 사용합니다.

반사의 장단점

장점 : 유연성 및 다양성
단점 : 코드 가독성 감소, 프로그램 성능

반영된 API

java.lang.reflect 包

  • 클래스 유형
  • 메서드 클래스 메서드
  • 필드 클래스 속성
  • 생성자 클래스 생성 방법

반사

반사를 사용하는 과정

  1. Class 객체 얻기
  2. Class 객체를 통해 클래스의 메서드와 속성을 얻습니다.
  3. 반사를 통해 개체 만들기
  4. 개체를 통해 메서드 및 속성 호출

클래스를 얻는 여러 방법

  1. 클래스에서 얻은 클래스 이름. 클래스
  2. Object.getClass () 객체에 의해 획득
  3. Class.forName ( "package name + class name")은 클래스를 메모리에 동적으로로드합니다.

런타임에 클래스 속성 및 메서드 정보 얻기

수업 방법 :

  • Method [] getDeclaredMethods () 선언 된 모든 메소드 가져 오기
  • Field [] getDeclaredFields ()를 사용하여 선언 된 모든 속성을 가져옵니다.

방법 방법 :

  • String getName () 메서드 이름을 가져옵니다.
  • 클래스 getReturnType () 반환 값 유형을 가져옵니다.
  • int getModifiers ()를 사용하여 액세스 수정자를 얻습니다.
  • Class [] getParameterTypes () 모든 매개 변수 유형 가져 오기

필드 방법 :

  • String getName () 메서드 이름을 가져옵니다.
  • 클래스 getType () 유형 가져 오기
  • int getModifiers ()를 사용하여 액세스 수정자를 얻습니다.

개체 생성, 메서드 및 속성 호출

수업 방법 :

  • Object newInstance () 객체를 생성하려면 매개 변수가없는 생성 메소드를 제공해야합니다.
  • getMethod (String name, Class ... paramType) 메소드는 특정 메소드
    이름 을 얻기위한 메소드 이름이고 paramType은 매개 변수의 유형입니다.

Method 클래스의 메서드 :

  • Object invoke (Object obj, Object ... params)
    obj는 메소드를 호출하는 객체이고 params는 매개 변수의 값입니다.

지정된 생성자 호출

수업 방법 :

  • 생성자를 얻기위한 생성자 getContructor (Class ... paramType)
    paramType은 생성자 의 매개 변수 유형입니다.

생성자 방법 :

  • Object newInstance (Object… params) Create object
    params는 매개 변수의 값입니다.

반사 케이스

사례 : 런타임에 클래스의 속성 및 메서드 정보 얻기

class Person{
	private String name;
	private Integer age;
	public Person(){
		
	}
	public Person(String name,Integer age){
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public void sayHi(){
		System.out.println("Hi:"+name+","+age);
	}
}
public class ReflectTest {

	public static void main(String[] args){
		try {
			//获得类型
			Class clazz = Person.class;
			//获得所有的属性
			Field[] fields = clazz.getDeclaredFields();
			for(Field f : fields){
				//属性名称
				String name = f.getName();
				//属性类型
				Class c = f.getType();
				System.out.println(name+" - "+c);
			}
			//获得所有的方法
			Method[] methods = clazz.getDeclaredMethods();
			for(Method m : methods){
				//方法名
				String name = m.getName();
				//返回值类型
				Class returnType = m.getReturnType();
				System.out.print(returnType + " " + name + "(");
				//参数
				Class[] params = m.getParameterTypes();
				for(Class c : params){
					System.out.print(" " + c.getName());
				}
				System.out.println(")");
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}

사례 : 객체 생성, 메서드 호출

try {
	//获得类型
	Class clazz = Person.class;
	//获得类的对象,调用默认的构造方法
	Object obj = clazz.newInstance();
	//获得对象的方法
	Method m1 = clazz.getMethod("setName", String.class);
	Method m2 = clazz.getMethod("setAge", Integer.class);
	Method m3 = clazz.getMethod("sayHi");
	//调用方法
	m1.invoke(obj, "micheal");
	m2.invoke(obj, 20);
	m3.invoke(obj);
} catch (Exception e) {
	e.printStackTrace();
} 

사례 : 지정된 구성 방법 호출

try {
	//运行时将Person类加载到内存中
	Class clazz = Person.class;
	//获得指定的构造方法
	Constructor con = clazz.getConstructor(String.class,Integer.class);
	//调用构造方法
	Object obj = con.newInstance("Jim",30);
	//调用方法
	Method m = clazz.getMethod("sayHi");
	m.invoke(obj);
} catch (Exception e) {
	e.printStackTrace();
} 

사례 : 리플렉션을 사용하여 JSON 구문 분석 완료

public class JSONUtils{
   /**
    * 解析JSON,返回Java对象
    * @param json JSON字符串
    * @param clazz Java类型
    * @return Java对象
    * @throws Exception
    */
    public static Object fromJSON(String json,Class clazz) throws Exception {
        Object obj = clazz.newInstance();
        //去掉JSON字符串前后{}和"
        json = json.replace("{", "").replace("}", "").replace("\"","");
        //按,分割字符串
        String[] strings = json.split("\\,");
        for(String str : strings){
            //再按:分割出属性名和属性值
            String[] strs = str.split("\\:");
            String name = strs[0];
            String value = strs[1];
            //获得属性
            Field field = clazz.getDeclaredField(name);
            //修改属性为可以访问,因为是private的
            field.setAccessible(true);
            Object val = null;
            //判断属性类型,转换值的类型
            if(field.getType() == Integer.class){
                val = Integer.valueOf(value);
            }else{
                val = value;
            }
            //属性赋值
            field.set(obj,val);
        }
        //返回对象
        return obj;
    }

	public static void main(String[] args) throws Exception {
        String json = "{\"name\":\"张三\",\"age\":\"20\"}";
        Person person = (Person) JSONUtils.fromJSON(json,Person.class);
        person.sayHi();
    }
}

종료

할당 : 리플렉션을 사용하여 Java 개체를 JSON으로 변환


다른 Java 지식을 배워야하는 경우 여기 에서 Java 요약에 대한 매우 상세한 지식을 찌르십시오.

추천

출처blog.csdn.net/u013343114/article/details/112980085