java反射你知多少

       无论是Java开发还是Android开发,反射的使用必不可少。反射可以通过类名或类对象获取一系列的类方法,类成员,基类以及类实现接口。总而言之,只要知道类名或类对象,类中的一切信息就显得透明化。

       那反射有什么作用呢?可以从以下几个方面来阐述其作用。

       1.解决Android编译期问题。

      Android开发中难免有些需求是要求进行基于系统源码开发的,但此时有些类或方法已经被系统封装开发者没有权限获取,那怎么解决呢,通过反射开发者就能绕过系统权限,获取对应的所需类信息。

       2.针对Android的热修复

       在一个需求多变的环境中,需求不可能一次性就想得非常透彻。有时软件已经发出发现有问题,需要及时修复。此时开发者就可以通过反射进行相应类中Bug修复,这为软件的热修复提供了便利。当然脚本软件的原理也是如此。

       3.绕过安全限制开发

      在开发中,难免会遇到基于源码开发。但不是源码中的所有类开发者都是可以调用。例如Android开发中,自定义对话框,安装程序等。其中的这些都是系统封装好的,开发者没有权限操作。这种情况只能通过反射绕过Android系统限制进行二次开发,这样对Android系统有更深的理解和更高的控制权。

  好了费话不多说,下面详细介绍下java反射的使用。

  (一)Class类对象的获取

            ImageUtils imageUtils = new ImageUtils();
            //第一种形式获得类对象
            Class c1 = ImageUtils.class;
            //第二种形式获取类对象
            Class c2 = imageUtils.getClass();
            //第三种形式获得类对象(其中forname中参数必须是含包名的类名全称)
            Class c3 = Class.forName("com.example.ImageUtils");
              //获取全称类名(带包名)
            System.out.println("className  =  "+ c1.getName());
              //获取类名(不带包名)
            System.out.println("class:"+c1.getSimpleName());
            System.out.println("className  =  "+ c2.getName());
            System.out.println("className  =  "+ c3.getName());
 主要有以上三种方式获取Class对象,以方便后期使用。其运行结果如下。

java反射你知多少_第1张图片java反射你知多少_第2张图片

  (二)某个类中的一些方法的获取

            ImageUtils imageUtils = new ImageUtils();
            Class c = imageUtils.getClass();
            //获得ImgeUtils中所有非public以及public方法
            Method mtd[] = c.getDeclaredMethods();
            //获取ImageUtils中的所有public方法
            Method methods[] = c.getMethods();
            //获取某个类中的某个方法(如:获取参数为int型的setI方法)
            Method m1 = c.getMethod("setI",new Class[]{int.class});
            Method m2 = c.getDeclaredMethod("setI",new Class[]{int.class});
            //获取某个类的构造方法
            Constructor obj1[] = c.getConstructors();
            Constructor obj2[] = c.getDeclaredConstructors();
            //获取某个带参数的构造方法
            Constructor obj3 = c.getConstructor(new Class[]{int.class});
            Constructor obj4 = c.getDeclaredConstructor(new Class[]{int.class});
            //获取基础类的一些信息
           Class cls = c.getSuperclass();
            //获取对应基础类中的方法
            Method base[] = cls.getDeclaredMethods();
            for (int i=0;i


  (三)获取类中某个方法的返回值以及参数类型

            ImageUtils imageUtils = new ImageUtils();
            Class c = imageUtils.getClass();
            //获得ImgeUtils中所有public方法
            Method mtd[] = c.getDeclaredMethods();
            for (int i = 0;i < mtd.length;i++){
               Class paramestype[] = mtd[i].getParameterTypes();
                Class returntype = mtd[i].getReturnType();
                System.out.println("returntype  =  "+ returntype.getName());
                for (int j = 0;j < paramestype.length;j++){
                    System.out.println("paramestype  =  "+ paramestype[j].getName());
                }
            }
  通过上面的操作可查看对应方法的参数以及返回值类型,没有返回值则返回void。其运行结果如下。

java反射你知多少_第3张图片
  

  (四)某个类中的成员变量的获取

            ImageUtils imageUtils = new ImageUtils();
            Class c = imageUtils.getClass();
            Field[] fields = c.getFields();
            for (int i=0;i
  通过上面的操作可获取对应的成员变量以及成员变量的类型。其运行结果如下。

java反射你知多少_第4张图片


  (五)通过反射设置某个成员变量的值

           ImageUtils imageUtils = new ImageUtils();
            Class c3 = Class.forName("com.example.ImageUtils");
            Method m = c3.getDeclaredMethod("setI",new Class[]{int.class});
            m.invoke(imageUtils,new Object[]{100});
            Method getMethod = c3.getDeclaredMethod("getI");
            System.out.println("i:     "+ getMethod.invoke(imageUtils));

  通过以上侧操作可动态修改并获取成员变量 i 值。其运行结果如下。

(注意:这里操作的ImageUtils对象必须同一个否者获取不到正确修改后的值,如使用m.invoke(c3.newInstance(),newObject[]{100})和getMethod.invoke(c3.newInstance())这样就获取不到i修改后的值,因为c3.newinstance()方法表示新建了一个对象,换句话说在这个对象中修改了i值,在另一个新建的对象中怎么会获取到i修改后的值)。



  好了java的反射的使用介绍到此结束。正式附上源码,以供有兴趣者研究与建议。

 1.基类(Utils)

package com.example;

/**
 * Created by jamy on 2017/3/24.
 */

public class Utils {
    public void print(){

    }

    public void Stop(){

    }
}
  2.实现的接口(FaceImage)

package com.example;

/**
 * Created by jamy on 2017/3/24.
 */

public interface FaceImage {
    void ImagePrint();
}
  3.测试类(ImageUtils)

package com.example;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;

import javax.imageio.ImageIO;

/**
 * Created by jinfangmei on 2017/3/24.
 */

public class ImageUtils extends Utils implements FaceImage{

    public int i=2;
    public String  Start = null;
    private String name = null;
    protected String password = null;
    private int m = 0;

    public static void ImgYin(String s,String ImgName){
        byte[] bytes = null;
        try{
            String str = s;
            File _file = new File(ImgName);
            Image src = ImageIO.read(_file);
            int wideth=src.getWidth(null);
            int height=src.getHeight(null);
            BufferedImage image=new BufferedImage(wideth,height,BufferedImage.TYPE_INT_RGB);
            Graphics g=image.createGraphics();
            g.drawImage(src,0,0,wideth,height,null);
            g.setColor(Color.RED);
            g.setFont(new Font("宋体",Font.PLAIN,20));
            Font aa=new Font("宋体",Font.PLAIN,20);

            g.drawString(str,wideth-150,height-10);
            g.dispose();
            ByteArrayOutputStream out1 = new ByteArrayOutputStream();
            saveImage(image, out1);
            bytes = out1.toByteArray();
            out1.close();
            FileOutputStream out2 = new FileOutputStream(ImgName);
            out2.write(bytes);
            out2.close();
        }
        catch(Exception e){
            System.out.println(e);
        }
    }

    public static void saveImage(BufferedImage img, OutputStream out1) throws Exception {
        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out1);
        encoder.encode(img);
    }

    @Override
    public void ImagePrint() {

    }

    private void getName(){

    }
    public int getI() {
        return i;
    }

    public void setI(int i) {
        System.out.print("ImagUtils i:  "+i+"\n");
        this.i = i;
    }

    public ImageUtils(){

    }

    public ImageUtils(int m){
        this.m = m;
    }
}
  4.主类(TestImageCollect)

package com.example;

public class TestImageCollect {

    public int i=0;
    public String  Start=null;
    private String end = null;

    public static void main(String[] args) {
        try {
//            ImageUtils imageUtils = new ImageUtils();
//            //第一种形式获得类对象
//            Class c1 = ImageUtils.class;
//            //第二种形式获取类对象
//            Class c2 = imageUtils.getClass();
//            //第三种形式获得类对象(其中forname中参数必须是含包名的类名全称)
//            Class c3 = Class.forName("com.example.ImageUtils");
//              //获取全称类名(带包名)
//            System.out.println("className  =  "+ c1.getName());
//              //获取类名(不带包名)
//            System.out.println("class:"+c1.getSimpleName());
//            System.out.println("className  =  "+ c2.getName());
//            System.out.println("className  =  "+ c3.getName());
            /*****************获取Class类中的一些方法***********************************************/
//            ImageUtils imageUtils = new ImageUtils();
//            Class c = imageUtils.getClass();
//            //获得ImgeUtils中所有非public以及public方法
//            Method mtd[] = c.getDeclaredMethods();
//            //获取ImageUtils中的所有public方法
//            Method methods[] = c.getMethods();
//            //获取某个类中的某个方法(如:获取参数为int型的setI方法)
//            Method m1 = c.getMethod("setI",new Class[]{int.class});
//            Method m2 = c.getDeclaredMethod("setI",new Class[]{int.class});
//            //获取某个类的构造方法
//            Constructor obj1[] = c.getConstructors();
//            Constructor obj2[] = c.getDeclaredConstructors();
//            //获取某个带参数的构造方法
//            Constructor obj3 = c.getConstructor(new Class[]{int.class});
//            Constructor obj4 = c.getDeclaredConstructor(new Class[]{int.class});
//            //获取基础类的一些信息
//           Class cls = c.getSuperclass();
//            //获取对应基础类中的方法
//            Method base[] = cls.getDeclaredMethods();
//            for (int i=0;i

  到此java的反射就简单的介绍到这。好久没有写博客了,比较激动,希望有意者多多建议与交流。不积跬步,无以至千里。哈哈。




       

你可能感兴趣的:(Android技术开发)