zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    HttpClient_4 用法 由HttpClient_3 升级到 HttpClient_4 必看
    环境变量设置错误导致全部命令无法使用解决办法
    正则表达式学习一
    opencv使用中的一点经验记录
    机器学习公开课回顾(一)
    bp算法的一个简单例子
    Ubuntu 16.04安装有道词典
    使用html2canvas库实现一个简单截图功能,还需优化
    PHP-MySQL连接封装-其他简单封装
    PHP获取客户端真实IP
  • 原文地址:https://www.cnblogs.com/tfil/p/14228148.html
Copyright © 2011-2022 走看看