关闭

黑马程序员 JAVA提高——反射

标签: java博客黑马程序员javase面向对象
390人阅读 评论(0) 收藏 举报
分类:

----------- android培训java培训java学习型技术博客、期待与您交流! ------------


java中的反射机制

一:什么是反射?

1,反射的概念:主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。反射本身并不是一个新概念,尽管计算机科学赋予了反射概念新的含义。在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representation)和监测(examination),并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。

2,java中的类反射:

反射是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查。
反射是 Java 被视为动态(或准动态)语言的关键,允许程序于执行期 反射API 取得任何已知名称之 class 的內部信息,包括 package、type parameters、superclass、implemented interfaces、inner classes, outer class, fields、constructors、methods、modifiers,並可于执行期生成实例、变更 字段內容或唤起 方法


java反射机制:   JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

一句话:java反射就是将类中的各个成分映射称为java类。

了解了反射的基本概念后,我们就要走进java反射,首先介绍反射的基石——Class类


二,Class类——反射的基石

java中万事万物皆为对象,那么在java中各种各样的java类又是不是一个对象呢,答案是肯定的。就是Class类。

具体来说:Class对象就是用来描述,那么描述类的那些属性呢。描述类的成员变量,方法,够着函数,及各种修饰符等等信息。

一句话Class对象就是用来描述java中类的信息的一种特殊的类。

注意:与class的区别,class是java中的关键字,而Class是java中的一个类。不要混淆

下面通过代码和注释简要说明下Class

package cn.itcast.day1;

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;

public class ReflectTest {
	public static void main(String[] args) throws Exception {
		String str1 = "abc";
                //获取Class对象的三种方法
                Class cls1 = str1.getClass();
		Class cls2 = String.class;
		Class cls3 = Class.forName("java.lang.String");
                //Class代表类的字节码文件,在内存中只有一份
                System.out.println(cls1 == cls2);
		System.out.println(cls1 == cls3);
		
		System.out.println(cls1.isPrimitive());//判断是不是基本类型
		System.out.println(int.class.isPrimitive());
		System.out.println(int.class == Integer.class);
		System.out.println(int.class == Integer.TYPE);
		System.out.println(int[].class.isPrimitive());
		System.out.println(int[].class.isArray());//判断是不是数组		
		}
}

三:反射的应用

1.java反射--Constructor

首先介绍一下Constructor类,这个类用来封装反射得到的构造器,Class有四个方法来获得Constructor对象

  • public Constructor<?>[] getConstructors()      返回类中所有的public构造器集合,默认构造器的下标为0
  • public Constructor<T> getConstructor(Class<?>... parameterTypes)   返回指定public构造器,参数为构造器参数类型集合
  • public Constructor<?>[] getDeclaredConstructors()  返回类中所有的构造器,包括私有
  • public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 返回任意指定的构造器

package cn.itcast.day1;

import java.lang.reflect.Constructor;


class Person{
	private String name;
	private int  age;
	
	public Person(){
		System.out.println("共有的空的构造函数");
	}
	private Person(String name){
		this.name = name ;
		System.out.println("私有的构造器");
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public String toString() {

		return this.name+"....."+this.age;
	}
	
	
}

public class Test {

	public static void main(String[] args) throws Exception {
		method();

	}

	private static void method() throws Exception{
		Person p = new Person();
		Class cls1 = p.getClass();
//		获取构造方法Constructor
//      getConstructor()  only for public 
//      getDeclaredConstructor()  global access all 
        
        //指定参数列表获取特定的方法
        Constructor con = cls1.getDeclaredConstructor(String.class);
        con.setAccessible(true); //设置可访问的权限,暴力反射,强行的使用私有的构造器
        Object obj = con.newInstance("zhangsan");
        System.out.println(obj);  //打印一下这个对象的信息
        
//获取所有的构造方法集合,返回构造器的数组
        Constructor con1[] = cls1.getDeclaredConstructors();
        System.out.println(con1.length);
	}

}

注意:

a:   获取构造方法Constructor中 getConstructor()和 getDeclaredConstructor()  的区别:
前者只是获取共有的构造器,而后者可以获取私有的构造器,当然需要:  con.setAccessible(true); //设置可访问的权限
b:newInstance()用来调用空的构造函数来实例化变量。否则的话就要传入相应的参数。


2,java反射——Field

 了解了构造器,其实你可以猜到成员变量的获取方法了,成员变量用Field类进行封装。

       主要的方法非常的类似:
  • public Field getDeclaredField(String name)  获取任意指定名字的成员
  • public Field[] getDeclaredFields()             获取所有的成员变量
  • public Field getField(String name)           获取任意public成员变量
  • public Field[] getFields()                          获取所有的public成员变量
代码说明:
private static void method_1() throws Exception {
		/**
         * 获取成员变量Field
         * getField()
         * getDeclaredField()
         * */
		Person p = new Person();
		Class cls1 = p.getClass();
        Field field = cls1.getDeclaredField("name");
        field.setAccessible(true);      
        System.out.println((String)field.get(p));
		
        Field[] fields = cls1.getDeclaredFields();
        for (Field f : fields){
        	System.out.println(f.getName());
        }
	}

分析:对比Constructor的学习,同理的
有一点注意:你要调用对象的字段,所以你要传入你要调用那个对象,这是很显然的。


2,java反射——Method

轻车熟路:同理先看Methodde 构造器:

  • public Method[] getMethods()    获取所有的共有方法的集合
  • public Method getMethod(String name,Class<?>... parameterTypes) 获取指定公有方法 参数1:方法名 参数2:参数类型集合  
  • public Method[] getDeclaredMethods()  获取所有的方法
  • public Method getDeclaredMethod(String name,Class<?>... parameterTypes) 获取任意指定方法
代码案例:

private static void method_2() throws Exception {
		/**
         * 调用类的方法 Method
         * getMethod()
         * getDeclaredMethod()
         * 
         * */
		Person p = new Person();
		Class cls1 = p.getClass();
        Method f = cls1.getMethod("getName", null);
        Object name = f.invoke(p, null);
        System.out.println((String)name);
		
        Method[] methods = cls1.getDeclaredMethods();
        
        for(Method method : methods){
        	System.out.println(method.getName());
        }
        
	}

总结:要想调用一个method实例,很容易的想到,要传给一个对象,即要调用那个对象的方法,自然还要传入,形参。

问题?若果一个方法伪静态的,不需要对象则传入null;



PS:反射的其他细节会在以后的博文中介绍



---- ASP.Net+Android+IOS开发.Net培训、期待与您交流!--------详细请查看:http://edu.csdn.net------






0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:7157次
    • 积分:203
    • 等级:
    • 排名:千里之外
    • 原创:14篇
    • 转载:0篇
    • 译文:0篇
    • 评论:1条
    文章分类
    文章存档
    最新评论