java反射

反射机制本质上就是一种用于实现动态编程的机制,可以在运行阶段动态的创建对象,并且动态的调用方法,具体功能由实参决定。反射技术破坏了面向对象,在底层发挥作用。

目前主流的框架SSH等底层是采用反射机制实现。java里的动态编程技术就是反射。

动态编程

编译期间变量的类型和调用的方法都不确定,运行时根据参数确定。动态编程可以让代码有更广泛的适应性,一段代码可以针对很多的类,但是程序的可读性非常低,编程难度也很高。

Class类

java.lang.Class类的实例可以描述java中的基本数据类型和引用数据类型。

该类没有公共的构造方法,是由java虚拟机和类加载器自动构造实例。

Class获取对象的方式

获取对象的作用:只有获得了对象,才能调用Class类中的方法

  1. 使用数据类型.Class的方式可以获取该类型的Class对象(重)
    【既能获取引用类型的Class对象,也可以获得基本数据类型的Class对象】
    Class c1 = String.class;
    System.out.println(“c1=”+c1); //自动调用toString,c1=class java.lang.String。类的完全限定名
    System.out.println(Integer.class);//class java.lang.Integer.类的完全限定名
    System.out.println(int.class); //int
    System.out.println(void.class); //void

    当Class对象为一个类类型时,toString 打印包名.类名
    当Class对象为一个基本数据类型时,toString直接打印该基本数据类型
    
  2. 使用对象.getClass()的方法可以获取该类型的Class对象
    【只能获取引用类型的Class对象,不能获取基本类型的Class对象】

    String s1 = new String("hello");
    System.out.println(s1.getClass());	//class java.lang.String
    Integer it1 = new Integer(10);
    System.out.println(it1.getClass());	//class java.lang.Integer
    int num = 20;
    System.out.println(num.getClass());	//error  int并不是一种引用类型
    
  3. 使用包装类.TYPE的方式来获取对应基本数据类型的Class对象
    【获取到基本数据类型】
    System.out.println(Integer.TYPE); //int
    System.out.println(Integer.class); //class java.lang.Integer

  4. 使用Class.forName()的方法可以获取参数类型的Class对象(重)
    System.out.println(Class.forName(“java.lang.String”)); //Class java.lang.String
    System.out.println(Class.forName(“String”)); //error 不能省略包名
    System.out.println(Class.forName(“int”)) //error 不能处理基本数据类型

java中创建对象的方法 (补充)
  1. new 直接创建 String str = new String ( ) ;

  2. 静态工厂方法方式 (单例模式获取对象的方式) Calendar cal = Calendar . getInstance ( ) ;

  3. 实例工厂方法方式 (通过一个对象 来获取另外一个对象) Date d = cal . getTime ( ) ;

  4. 反射
    //使用反射机制来创建对象
    //1.获取Class对象,调用forName()方法
    Class c1 = Class.forName(“xdl.day21.Person”);
    //2.创建该Class对象对应类的实例,调用newInstance()方法
    System.out.println(c1.newInstance());//创建Person类型的实例 null

    //使用反射机制并有参形式来创建对象
    //1.获取Class对象,调用forName()方法,使用上述Class对象即可
    Class c1 = Class.forName("xdl.day21.Person");
    //2.获取Constructor类型的对象,调用getConstructor()方法
        获取构造方法相当于将Person类中的Person(String name,int age)构造方法获取到了
    Constructor ct1 = c1.getConstructor(String.class, int.class);
    //3.使用有参构造方法来创建Class对象表示类的新实例
        调用newInstance()方法使用ct1表示的Person(String name, int age)构造方法来构造对象
    System.out.println(ct1.newInstance("zhangfei", 30));//zhangfei 30
    
反射中涉及到的包与类

软件包 java.lang.reflect 的描述

提供类和接口,以获得关于类和对象的反射信息。在安全限制内,反射允许编程访问关于加载类的字段、方法和构造方法的信息,并允许使用反射字段、方法和构造方法对其底层对等项进行操作。

Array提供动态创建和访问数组的静态方法。

java.lang.Class   用来描述其它类类型的一个类型   
java.lang.reflect.Constructor  构造类型  描述构造函数的 
java.lang.reflect.Feild    描述字段的类型  
java.lang.reflect.Method   描述方法的类型 
java.lang.reflect.Array    动态数组 
Class 类型中常用的API
static Class<?> forNmae(String className) - 获取参数指定类名的Class对象并返回
---------------------------------------------------------------------------------------
调用无参构造
T newInstance() - 用于获取该Class引用表示的类的一个新实例。

调用有参构造
Constructor<T> getConstructor(Class<?>... parameterTypes) 
		- 根据参数指定的类型来获取该Class对象表示类中的一个公共构造方法(...为变长数组)
Constructor<?>[]  getConstructors() - 获取该Class对象表示类中的所有公开构造方法
Constructor  getDeclaredConstructor() - 获取该Class对象表示类中的构造方法(包括公、私、保)
Constructor getDeclaredConstructor() - 获取该Class对象表示类中的所有构造方法。
---------------------------------------------------------------------------------------
获取成员变量
Field getDeclaredField(String name) - 获取该Class对象表示类中名字为name的成员变量并返回
Field[] getDeclaredFields() - 获取该Class对象表示类中所有的成员变量并返回
---------------------------------------------------------------------------------------
获取成员方法
Method getMethod(String name, Class<?>... parameterTypes) 
		- 获取该Class对象表示的类或接口中名字为name,参数为parameterTypes的公共成员方法并返回
Method[] getMethods() - 获取该Class对象表示类中所有的公共成员方法并返回

Constructor 类

Constructor 是用于描述Class对象对应类中的单个构造方法。  即用于描述构造方法

T newInstance(Object... initargs) - 使用当前调用对象表示的构造方法来构造Class对象表示类的新实例,调用构造方法的实参由该方法的形参传入。即创建一个对象,并用指定的初始化参数初始化该实例。 

int getModifiers() - 以整数形式返回构造方法的修饰符。

Field 类

Field类用于描述Class对象对应类中的单个成员变量。
通过Field给具体的对象赋值:赋值使用set(具体的对象,值);获取值使用get(具体的对象);
如果要访问私有属性需要使用setAccesible(true);

Object get(Object obj) - 获取对象obj中成员变量的数值并返回。
String getName() - 获取当前调用对象中成员变量的名称并返回。
Class<?> getType() - 返回当前调用对象所表示字段的类型。
void set(Object obj, Object value) - 将对象obj中的成员变量值改为value。

void setAccessible(boolean flag) - 用于设置是否进行java语言访问检查
设置为true,即取消java语言的访问检查

Method 类

Method 用于描述Class对象对应类中的单个成员方法。 
String getName() - 以 String 形式返回此 Method 对象的方法名。 
getReturnType() - 返回该方法的返回值类型。
int getModifiers() - 以整数形式返回该方法的修饰符。 
          
【Object invoke(Object obj, Object... args)】
      - 使用obj对象调用带有指定参数的方法,实参传递args。

代码实现

public static void main(String[] args) throws Exception {
	//1.获取Class对象,调用forName()方法
	Class<?> c1 = Class.forName("xdl.day21.Person");
	//2.使用有参的形式创建Person类型的对象,调用getConstructor()方法
	Constructor<?> ct1 = c1.getConstructor(String.class, int.class);
	//3.使用Constructor类型的引用去构造对象,调用newInstance()方法
	Person p1 = (Person) ct1.newInstance("zhangfei", 30);
	//4.获取Person类中名字为getName()的方法,调用getMethod()方法
	Method m1 = c1.getMethod("getName");
	//5.调用getName()方法,使用Method类型的引用调用invoke()方法
	//p1.getName()
	System.out.println(m1.invoke(p1)); //zhangfei
}
JavaBean内省
javabean是符合一定规范的可复用的java类。本质上就是一种习惯性编程规范,并不是明确的编程规则/语法格式
内省技术(Introspector )是针对javabean另一套和反射技术一样的获取类信息的API。

需要符合以下规范:
    a.要求满足JavaBean规范的类必须在一个包中。
    b.要求满足JavaBean规范的类必须提供无参的构造方法。
    c.要求满足JavaBean规范的类中成员变量都是私有的。
    d.要求满足JavaBean规范的类中提供公有的get成员变量和set成员变量的方法。
    e.要求满足JavaBean规范的类需要支持序列化操作。

boolean 类型的get()方法 以 is开头 
一般要实现序列化接口(什么也不做,只是做个标记)
1.对象形式的文件读写:如磁盘的读写需要实现序列化	2.网络传输
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值