Java 反射编程(上)

反射的泛型就是用?来描述

反射与类的操作 (取得父类信息)

利用反射可以做出一个对象所具备的所有操作行为, 而且最关键的是这一切的操作都可以基于Object类型进行.

取得父类信息

在Java 里面任何的程序类实际上都要求一定会有一个父类, 在 Class类里面就可以通过此方式来取得父类或者是实现的父接口, 有如下的俩个方法提供:

1. 获得本类的包名称:

public Package getPackage()
  • 1

2. 取得父类的Class 对象

public Class<? super T> getSuperclass()
  • 1

3. 取得父类接口

public Class<?>[] getInterfaces()
  • 1

通过反射可以取得类结构上的所有关键信息

案例: 使用上述方法

package com.record;

interface IMessage{
	
}
interface IFruit{
	
}

class Person implements IFruit,IMessage{
	public void print() {
		
	}
}

public class TestDemo {
	public static void main(String[] args) {
		// 方式一
		Person person = new Person();
		person.print();
		
		//反射实现
		Class<?> cls = Person.class;
		
		System.out.println(cls.getName());  // 获得本对象所属的全类名
		System.out.println(cls.getPackage().getName()); // 获得本类的包名称
		System.out.println(cls.getSuperclass().getName()); // 获得父类的Class对象
		
		Class<?> itf [] = cls.getInterfaces();  // 获得父类所有接口
		for (int x = 0; x < itf.length; x++) {
			System.out.println(itf[x].getName());
		}
		
	}
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

反射与类的操作 (反射调用构造)

反射调用构造

一个类中可以存在多个构造方法, 那么如果要想取得类中构造的调用, 就可以使用 Class 类提供的两个方法

1. 取得指定参数类型的构造

public Constructor<T> getConstructor(Class<?>... parameterTypes)
                              throws NoSuchMethodException,
                                     SecurityException
  • 1
  • 2
  • 3

2. 取得类中的所有构造

public Constructor<?>[] getConstructors()
                                 throws SecurityException
  • 1
  • 2

以上两个方法返回的都是 java.lang.reflect.Constructor<T> 类的实例化对象, 这个类里面要重点关注一个方法:

实例化对象:

public T newInstance(Object... initargs)
              throws InstantiationException,
                     IllegalAccessException,
                     IllegalArgumentException,
                     InvocationTargetException
  • 1
  • 2
  • 3
  • 4
  • 5

案例: 取得类中的所有构造方法信息.

package com.record;

import java.lang.reflect.Constructor;

class Person{
	public Person() {}
	public Person(String name) {}
	public Person(String name, int age) {}
}

public class TestDemo {
	public static void main(String[] args) throws Exception{
		Class<?> cls = Person.class;
		Constructor<?> conts[] = cls.getConstructors();
		for (int x = 0; x < conts.length; x++) {
			System.out.println(conts[x].toString());
		}
	}
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

在这里插入图片描述
以上操作是直接利用了 Constructor 类中的 toString () 方法 取得构造方法的完整信息, 而如果只是使用 getName() 方法就会比较麻烦了.
在这里插入图片描述
所以, getName() 只能取出 方法的名称.

改进: 使用getName() 方法取得构造方法完整信息

使用方法一: 获得修饰符的信息 (依然是 java.lang.reflect.Constructor<T> 类中)

public int getModifiers()
  • 1

结合 Modifier 类中的 toString() 方法实现

public static String toString(int mod)
  • 1

使用方法二 : 获得方法中的详细参数信息

public Class<?>[] getParameterTypes()
  • 1

使用方法三 : 获得方法中的异常抛出信息

public Class<?>[] getExceptionTypes()
  • 1

案例实现: 自己拼凑构造方法

package com.record;

import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;

class Person{
	public Person() throws Exception {}
	public Person(String name) throws RuntimeException,Exception {}
	public Person(String name, int age)  throws Exception {}
}

public class TestDemo {
	public static void main(String[] args) throws Exception{
		Class<?> cls = Person.class;
		Constructor<?> conts[] = cls.getConstructors();
		for (int x = 0; x < conts.length; x++) {
			System.out.print(Modifier.toString(conts[x].getModifiers())+" ");
			System.out.print(conts[x].getName()+"(");
			Class<?> params [] = conts[x].getParameterTypes();
			for (int y = 0; y < params.length; y++) {
				System.out.print(params[y].getName());
				if (y< params.length -1) {
					System.out.print(",");
				}
			}
			System.out.print(")");
			
			Class<?> exps [] = conts[x].getExceptionTypes();
			if (exps.length > 0) {  // 表示有异常
				System.out.print(" throws ");
				for (int i = 0; i < exps.length; i++) {
					System.out.print(exps[i].getName());
					if (i<exps.length -1) {
						System.out.print(",");
					}
				}
				System.out.println();
			}
			
		}
	}
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

在这里插入图片描述

重点:

要理解为什么在定义简单 java 类的时候一定要保留有一个无参构造

案例: 观察 Class 实例化对象的问题

package com.record;

class Person {
	private String name;
	private int age;

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	
}

public class TestDemo {
	public static void main(String[] args) throws Exception {
		Class<?> cls = Person.class;
		System.out.println(cls.newInstance());
	}
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

在这里插入图片描述
Class 类通过反射实例化对象的时候, 只能够调用类中的无参构造, 那么如果类中没有无参构造, 无法使用 Class类操作, 只能通过明确的构造调用执行实例化处理

案例: 要通过 Constructor 类实例化对象

package com.record;

import java.lang.reflect.Constructor;

class Person {
	private String name;
	private int age;

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	
}

public class TestDemo {
	public static void main(String[] args) throws Exception {
		Class<?> cls = Person.class;
		// 在明确表示取得指定参数类型的构造方法对象
		Constructor<?> cont = cls.getConstructor(String.class, int.class);
		System.out.println(cont.newInstance("张三",15));
	}
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

在这里插入图片描述

原文章:https://blog.csdn.net/Beyond_Nothing/article/details/112058389

原文地址:https://www.cnblogs.com/tfil/p/14228148.html