天天看点

(八)黑马程序员——反射

------- <a href="http://www.itheima.com" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="blank">android培训</a>、

<a href="http://www.itheima.com" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="blank">java培训</a>、期待与您交流! ----------

A.类的加载概述

当程序使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,链接,初始化来实现对类的初始化。      * 加载 

        * 就是指将class文件读入内存,并为之创建一个Class对象。任何类被使用时系统都会建立一个Class对象。

   * 连接

        * 验证 是否有正确的内部结构,并和其他类协调一致

        * 准备 负责为类的静态成员分配内存,并设置默认初始化值

        * 解析 将类的二进制数据中的符号引用替换为直接引用

   * 初始化  就是我们以前讲过的初始化步骤

 B:加载时机

  * 创建类的实例

    * 访问类的静态变量,或者为静态变量赋值

    * 调用类的静态方法

    * 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象

    * 初始化某个类的子类

    * 直接使用java.exe命令来运行某个主类

类加载器的概述和分类:

    A:类加载器的概述

            负责将。class文件加载到内存中,并为之生成对应的Class对象。虽然我们不需要关心加载机制,但是了解这个我们能更好地理解和运行程序。

    B:类的加载分类

根类加载器:Bootstrap ClassLoader 扩展类加载器:Extension ClassLoader 系统类加载器:System ClassLoader

C:类加载器的作用

根类加载器:!1.引导类加载器,负责Java核心类的加载            扩展类加载器: 2.扩展类加载器,负责目录中jar包的加载 系统类加载器:3.负责在jvm启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径

反射概述

*Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法 *对于任意一个类对象,都能够调用它的任意一个方法和属性: 这种动态获取的信息以及动态调用的任意一个方法和属性: 要想解剖一个类,必须先要获取到该类的字节码文件对象。 而解剖使用的就是class类中的方法,所以先要获取到么一个字节码对应的class类型的对象。

B:三种方式

*a:object类的 getClass()方法,判断俩个对象是同一个字节码文件 *b:静态属性class,锁对象 *c:class类中的静态方法forName(),读取配置文件

反射——通过反射获取带参构造方法并使用

Constructor

       class类中newInstance()方法是使用该类无参的构造函数创建对象,如果一个类没有无参的构造函数,就不能这样创建了,可以调用class类的getConstructor(String。          class,int.class)方法获取一个指定的构造函数然后Constructor类的newInstance(“张三”,20)方法创建对象        反射——通过反射获取成员变量并使用

Filed

        *class.getFIled(String)方法可以获取类中的指定字段(可见的),如果是私有的可以用getDeclaedFiled("name")方法获取,通过set(obj,“李四”)方法可以设置指定对象上         该字段的值,如果是私有的需要先调用setAccessible(true)设置访问权限,用获取的指定的字段调用get(obj)可以获取指定对象中该字段值       反射——通过反射获取方法并使用

Method

         *class.getMethod(String,class....)方法可以获取类中的指定方法,class.getDeclareMethod(String,class...)"方法获取类中的指定方法如果调用的可以用invoke("name")       方法invoke(object,object.....)可以调用该方法,class.getMethod("eat") invoke(obj)Class.getMethod("eat",int.class) inhjvooke(obj,10) 反射——通过反射越过泛型检查 ArraryList<Integer>的一个对象,在这个集合中添加字符串数据,如何实现呢?

package it.heima.text;
import java.lang.reflect.Method;
import java.util.ArrayList;


public class Text1 {
public static void main(String[] args) throws Exception {
//创建Arraylist集合
ArrayList<String> list = new ArrayList<String>();
//添加字符串
list.add("abc");
list.add("def");
//获取字节码文件
Class clazz=Class.forName("it.heima.text");
//获取里面的方法
Method m=clazz.getMethod("add", Object.class);
//执行
m.invoke("add", list);
System.out.println(list);
}
}
           

反射——通过反射写一个通过某个对象属性未指定得值

            * public void setProperty(Object obj, String propertyName, Object value){},此方法可将obj对象中名为propertyName的属性的值设置为value 。

package it.heima.text;


public class Text3 {
/**
* * A:案例演示
* public void setProperty(Object obj, String propertyName, Object value){},
* 此方法可将obj对象中名为propertyName的属性的值设置为value。
* @throws Exception 
*/
public static void main(String[] args) throws Exception {
Student s=new Student();
System.out.println(s);
Tool t=new Tool();
t.setProperty(s, "张三", 23);
System.out.println(s);
}
}
package it.heima.text;


public class Student {
private String name;
private int age;
public Student(){
super();
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
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 "Student [name=" + name + ", age=" + age + "]";
}
}
package it.heima.text;


import java.lang.reflect.Field;


public class Tool {
public void setProperty(Object obj,String PropersyName,Object value) throws Exception{
//获取字节码文件
Class clazz=obj.getClass();
//暴力去反
Field f=clazz.getDeclaredField(PropersyName);
//去掉权限
f.setAccessible(true);
//设置值
f.set(obj, value);
}


}
           

反射_(练习)        * 已知一个类,定义如下: 

       * package cn.itcast.heima;

       *         public class DemoClass {

                public void run() {

                    System.out.println("welcome to heima!");

                }

            }

     * (1) 写一个Properties格式的配置文件,配置类的完整名称。 

     * (2) 写一个程序,读取这个Properties配置文件,获得类的完整名称并加载这个类,用反射的方式运行run方法。

package it.heima.text;


import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;


/*思路
 * 1.通过创建输入流关联“xxx.properties”
 * 2.读取这个配置文件获取这个类中的所有名称并且加载这个类,通过反射来运行run方法
 * 
 * */

public class Text2 {
public static void main(String[] args) throws Exception {
// 1.通过创建输入流关联“xxx.properties”
BufferedReader br=new BufferedReader(new FileReader("xxx.propertise"));
//获取“xxx.properties”的字节码
Class clazz=Class.forName(br.readLine());
//创建新实例
   DemoClass c=(DemoClass) clazz.newInstance();
   //运行run方法
c.run();
}
}
package it.heima.text;


public class DemoClass {
public void run() {

}
}
           

动态代理

package it.heima动态代理;


import java.lang.reflect.Proxy;


public class Demo {
public static void main(String[] args) {
Method methodimpl = new Methodimpl();
methodimpl.login();
methodimpl.submit();

System.out.println("---------");

MyInvocationHandler_Demo proxy = new MyInvocationHandler_Demo(methodimpl);
Method mProxy = (Method) Proxy.newProxyInstance(
methodimpl.getClass().getClassLoader() ,
methodimpl.getClass().getInterfaces(), 
proxy);
mProxy.login();
mProxy.submit();
}
}


package it.heima动态代理;


public interface Method1 {
public void login();
public void submit();


}


package it.heima动态代理;


public class Methodimpl implements Method {


@Override
public void login() {
System.out.println("实际:登陆");
}


@Override
public void submit() {
System.out.println("实际:提交");
}
}


package it.heima动态代理;


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;


public class MyInvocationHandler_Demo implements InvocationHandler {
private Object target;


public MyInvocationHandler_Demo(Object target) {
this.target = target;
}


@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("代理前:权限校验");
method.invoke(target, args);
System.out.println("代理后:日志记录");
return null;
}
}
           
</pre><pre code_snippet_id="1608606" snippet_file_name="blog_20160313_6_2623684" name="code" class="java">
package it.heima动态代理;


public interface Method {
<span style="white-space: pre;"></span>
<span style="white-space: pre;"></span>public void login();
<span style="white-space: pre;"></span>
<span style="white-space: pre;"></span>public void submit();


}
           

package it.heima动态代理;

public interface Method {

public void login();

public void submit();

}