java学习笔记之反射机制

认识Class类

正常方式
引入需要的包,类名称
通过new实例化
取得实例化对象
反射方式
getClass方法
得到完整的包,类名称
  • 所有类的对象实际上都是Class类的实例
  • Class类常用方法
  • 实例化Class类对象的三种方法
package study;

import java.lang.*;

class X{
}

public class demo {
    public static void main(String[] args) {
        Class<?>c1=null;
        Class<?>c2=null;
        Class<?>c3=null;
        try{
            c1=Class.forName("study.X");  //最常用的形式
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }
        c2=new X().getClass();//通过Object类中的方法实例
        c3=X.class;//通过类.Class实例化
        System.out.println("类名称");
        System.out.println(c1+"\t"+c2+"\t"+c3);
    }
}

Class类的使用

  • 通过无参构造实例化对象,通过newInstance
  • 调用有参构造实例化对象
    1.通过Class类中的getConstructors()取得本类中所有的构造方法
    2.向构造方法中传递一个对象数组进去,里面包含了构造方法中所需的各个参数
    3.之后通过Constructor实例化对象
  • Constructor常用方法

   package study;
import java.lang.*;
class Person {
    private String name;
    private int age;
    //public Person(String name,int age){
    // this.name=name;
    // this.age=age;
    //}
    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String toString() {
        return "姓名" + this.name + "年龄" + this.age;
    }
}

public class demo {
    public static void main(String[] args) {
      Class<?> c=null;
      try{
          c=Class.forName("study.Person");
      }catch (ClassNotFoundException e){
          e.printStackTrace();
      }
      Person per=null;
      //Constructor<?> cons[]=null;
      //cons=c.getConstructors();
      try{
        per=(Person)c.newInstance();
        //per=(Person)cons[0].newInstance("小明",30);
      }catch (Exception e){
          e.printStackTrace();
      }
      per.setAge(15);
      per.setName("小明");
        System.out.println(per);
    }
}

反射的应用

  • Constructor:表示类中的构造方法
  • Field:表示类中的属性
  • Method:表示类中的方法
    (三个类都是AccessibleObject类的子类)

1.取得所实现的全部接口(getInterfaces())

   Class<?>c1=null;
   try
   { c1=Class.forName("study.Person");}
  catch(ClassNotFoundException e)
   {e.printStackTrace();}
   Class<?>c[]=c1.getInterfaces();
   for(int i=0;i<c.length;i++){System.out.println("实现的接口名称"+c[i].getName);}   

2.取得父类(getSuperclass(),getName())
3.取得全部构造方法(Constructors类
)

  • 取得Person类中的全部构造方法
  • 取得一个类的全部构造方法
1.
Constructors<?> con[]=c1.getConstructors();
for(int i<con.length) System.out.println(con[i]);
2.
for(i<con.length){
Class<?>p[]=con[i].getParameterTypes();  //列出构造中的参数类型
"构造方法:"+Modifier.toString(con[i].getModifiers());//取出权限
 +con[i].getName();//输出构造方法名称
 for(j<p.length){
   p[j].getName()+"arg"+i;
  }
}
//输出结果:构造方法: public study.Person(){}  or (java.lang.String arg1,int arg2){}

4.取得全部方法(Method类)
5.取得全部属性(Field类)

  • 得到实现的接口或父类中的公共属性:public Field[] getFields() throws SecurityException
  • 得到本类中的全部属性:public Field[] getDeclaredFields() throws SecurityException
  • 以上返回的都是Field数组,每一个Field对象表示类中的一个属性
  • Field类常用方法
  • 可用getModifiers().toString()取得修饰符

java反射机制的深入应用

通过反射调用类中的方法
如果要使用反射调用类中的方法可以通过Method类完成,操作步骤如下:
(1)通过Class类的getMethod(String name,Class…parameterTypes)方法取得一个Method的对象,并设置此方法操作时所需要的参数类型
(2)之后可以使用invoke()进行调用,并向方法中传递要设置的参数

Class.forName()-------1.实例化Class--->Person
getMethod("sayChina")--------2.找到sayChina()--->+sayChina():void
invoke()------->3.调用方法--->+sayChina():void

调用setter及getter方法

package study;

import java.lang.*;
import java.lang.reflect.Method;

class Person {
   private String name;
   private int age;
   public Person(){

   }
  public Person(String name){
      this.setName(name);
  }
  public Person(String  name,int age){
       this.name=name;
      this.age=age;
  }

   public int getAge() {
       return age;
   }

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   public void setAge(int age) {
       this.age = age;
   }

   @Override
   public String toString() {
       return "姓名" + this.name + "年龄" + this.age;
   }
}

public class demo {
   public static void main(String[] args) {
       Class<?> c1 = null;
      Object obj=null;
      try{
          c1=Class.forName("study.Person");
      }catch (ClassNotFoundException e){
          e.printStackTrace();
      }
      try{
          obj=c1.newInstance();
      }catch (InstantiationException e){
          e.printStackTrace();
      }catch (IllegalAccessException e){
          e.printStackTrace();
      }
      setter(obj,"name","小明",String.class);
      setter(obj,"age",15,int.class);
       System.out.println("姓名:");
       getter(obj,"name");
       System.out.println("年龄:");
       getter(obj,"age");
   }
   public static void setter(Object obj,String att,Object value,Class<?>type){
        try{
            Method met=obj.getClass()
                    .getMethod("set"+initStr(att),type);
            met.invoke(obj,value);
        }catch (Exception e){
            e.printStackTrace();
        }
   }
   public static  void getter(Object obj,String att){
       try{
           Method met=obj.getClass().getMethod("get"+initStr(att));
       }catch (Exception e){
           e.printStackTrace();
       }
   }
   public static String initStr(String old){
       String str=old.substring(0,1).toUpperCase()+old.substring(1);
       return  str;
   }

}

通过反射操作属性
通过反射操作数组

  • 可以通过Class类的以下方法取得一个数组的Class对象

public Class<?>getComponentType()

  • 在反射操作抱java.lang.reflect中使用Array类表示一个数组,可以通过此类取得数组长度,取得数组内容的操作
  • Array类的常用方法

动态代理

可以通过一个代理类完成全部的代理功能,那么此时就必须使用使用动态代理完成.
在java中实现动态代理机制,则需要java.lang.reflect.InvocationHandler接口和java.lang.reflect.Proxy类的支持
在此接口中只定义了一个invoke()方法,此方法有三个参数,其参数的意义如下.
Object proxy:被代理的对象
Method method:要调用的方法
Object args[]:方法调用时所需要的参数
Proxy类是专门完成代理的操作类,可以通过此类为一个或多个接口动态地生成实现类.Proxy提供了如下的操作方法:
通过newProxyInstance()方法可以动态地生成实现类,在此方法中的参数意义如下.
ClassLoader loader:类加载器
Class<?>[]interfaces:得到全部的接口
InvocationHandler h:得到InvocationHandler接口的子类实例

类的生命周期

在这里插入图片描述

工厂设计模式

将反射机制应用在工厂模式上

package study;

import java.io.FileInputStream;
import java.lang.*;
import java.lang.reflect.Method;
interface Fruit{
    public void eat();
}
class Apple implements Fruit{
      public void eat(){
          System.out.println("吃苹果");
      }
}
class Orange implements  Fruit{
    public void eat() {
        System.out.println("吃橘子");
    }
}
class Factory{
     public static Fruit getInstance(String className){
         Fruit fruit=null;
         try{
             fruit=(Fruit)Class.forName(className).newInstance();//实例化对象
         }catch (Exception e){
             e.printStackTrace();
         }
         return fruit;
     }
}
public class demo {
    public static void main(String[] args) {
        Fruit f=Factory.getInstance("study.Apple");
        if(f!=null) f.eat();
    }
}

结合属性文件的工厂模式

package study;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.lang.*;
import java.lang.reflect.Method;
import java.util.Properties;

interface Fruit{
    public void eat();
}
class Apple implements Fruit{
      public void eat(){
          System.out.println("吃苹果");
      }
}
class Orange implements  Fruit{
    public void eat() {
        System.out.println("吃橘子");
    }
}
class Factory{
     public static Fruit getInstance(String className){
         Fruit fruit=null;
         try{
             fruit=(Fruit)Class.forName(className).newInstance();//实例化对象
         }catch (Exception e){
             e.printStackTrace();
         }
         return fruit;
     }
}
class  init{
     public  static Properties getPro(){
         Properties pro=new Properties();
         File f=new File("d:\\fruit.properties");
         try{
             if(f.exists()){
                 pro.load(new FileInputStream(f));
             }
             else {
                 pro.setProperty("apple", "study.Apple");
                 pro.setProperty("orange", "study.Orange");
                 pro.store(new FileOutputStream(f), "FRUIT CLASS");
             }
         }catch (Exception e){
             e.printStackTrace();
         }
         return pro;
     }
}
public class demo {
    public static void main(String[] args) {
        Properties pro=init.getPro();
        Fruit f=Factory.getInstance(pro.getProperty("apple"));
        if(f!=null) f.eat();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值