JAVA学习笔记(六十一)- 反射Reflection

反射Reflection

import java.lang.reflect.Modifier;

/*
 * 反射Reflection
 * java.lang.Class类
 */
public class Test01 {
    public static void main(String[] args) {
        String name = "tom";

        // 方式一:通过对象getClass()方法
        // 任意一个类的对象,都有一个getClass()方法
        // 可以通过此获取获取当前对象的类型所对应的Class对象
        Class cls = name.getClass();
        showInfo(cls);

        //方式二:通过Class类的forName()静态方法
        try {
            Class cls2=Class.forName("com.itany.basejava.day37.Test01");
            showInfo(cls2);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        //方式三:通过指定类的class属性
        Class cls3=Student.class;
        showInfo(cls3);

    }

    // 获取Class对象的相关信息
    public static void showInfo(Class cls) {
        System.out.println("类的全名:" + cls.getName());
        System.out.println("类名:" + cls.getSimpleName());
        System.out.println("所属包:" + cls.getPackage());
        System.out.println("是否为本地类:" + cls.isLocalClass());
        System.out.println("是否为接口:" + cls.isInterface());
        System.out.println("是否为数组:" + cls.isArray());
        System.out.println("是否为基本数据类型:" + cls.isPrimitive());
        // 获取其父类的Class对象
        Class superCls = cls.getSuperclass();
        System.out.println("父类的全名:" + superCls.getName());
        // 获取类的修饰符
        int m = cls.getModifiers();
        System.out.println("修饰符为:");
        if (Modifier.isPublic(m)) {
            System.out.print("public ");
        }
        if (Modifier.isStatic(m)) {
            System.out.print("static ");
        }
        if (Modifier.isAbstract(m)) {
            System.out.print("abstract ");
        }
        if (Modifier.isFinal(m)) {
            System.out.print("final ");
        }
        System.out.println("**************************************\n");
    }
}

通过反射访问构造方法,实例化对象

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

/*
 * 通过反射访问构造方法,实例化对象
 * Constructor类
 */
public class Test03 {
    public static void main(String[] args) throws Exception {
        // 创建一个Dog类的对象
        // Dog dog1=new Dog("大黄", 3, "男");

        // 创建一个Dog类的Class对象
        Class<Dog> cls = Dog.class;

        /*
         * 实例化无参构造函数的对象,两种方式
         */
        // 1.通过Class对象的newInstance()方法创建实例,只适用于通过无参构造方法创建对象
        Dog dog = (Dog) cls.newInstance();
        // dog.show();
        Method method = cls.getDeclaredMethod("show");
        method.invoke(dog);
        System.out.println("*************************\n");

        // 2.获取参数为空的构造方法
        Constructor c = cls.getDeclaredConstructor();
        Dog dog2 = (Dog) c.newInstance();
        dog2.show();
        System.out.println("*************************\n");

        /*
         * 实例化带参构造方法的对象
         */
        Constructor c2 = cls.getDeclaredConstructor(new Class[] { String.class,
                int.class, String.class });
        Dog dog3 = (Dog) c2.newInstance("小黄", 2, "女");
        dog3.show();

        /*
         * 通过private修饰的构造方法实例化对象
         */
        Constructor<Dog> c3 = cls.getDeclaredConstructor(new Class[] {
                String.class, String.class });
        c3.setAccessible(true);
        Dog dog4=c3.newInstance("巨黄","中");
        dog4.show();

    }
}

/*
 * Animal父类
 */
class Animal {
    public String name;
    int age;

    public Animal() {
        System.out.println("父类无参的构造方法");
    }

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("父类中带参的构造方法");
    }

    public void show() {
        System.out.println("父类中的show方法");
    }
}

/*
 * Dog类,继承自Animal
 */
class Dog extends Animal {
    String sex;

    public Dog() {
        System.out.println("子类中无参的构造方法");
    }

    public Dog(String name, int age, String sex) {
        System.out.println("子类中带参的构造方法");
    }

    private Dog(String name, String sex) {
        System.out.println("子类中带两个参数的构造方法");
    }

    // 重写父类中的show方法
    public void show() {
        System.out.println("子类中的show方法");
    }

}

Field类

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/*
 * Field类
 */
public class Test02 {
    public static void main(String[] args) throws SecurityException,
            NoSuchFieldException, IllegalArgumentException,
            IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        // 创建一个Student类的对象,即学生对象
        Student stu1 = new Student();
        Student stu2 = new Student();
        // 创建一个Student类对象,即Student类的Class对象
        Class cls = Student.class;

        /*
         * Field属性操作;
         */
        // 1.获取Student类中的所有属性,包含本类和父类中所有public修饰的所有属性
        // Field[] fields = cls.getFields();
        // 2.获取Student类中的所有属性,包含本类中的任意修饰符修饰的所有属性
        Field[] fields = cls.getDeclaredFields();
        for (Field f : fields) {
            System.out.println(f.getName());
            // System.out.println(f.toString());
        }
        System.out.println("**********************\n");
        // 3.获取Student类中指定的属性
        Field name = cls.getField("name");
        Field grade = cls.getDeclaredField("grade");
        Field sex = cls.getSuperclass().getDeclaredField("sex");
        // 为属性赋值
        // stu1.name="tom";//直接通过对象名.属性名赋值
        name.set(stu1, "alice");// 为指定对象的属性赋值
        System.out.println("stu1的name:" + name.get(stu1));
        // 设置属性为可访问,即设置访问修饰符
        grade.setAccessible(true);
        grade.set(stu1, 2);// 为stu1的私有属性grade赋值
        System.out.println("stu1的grade:" + grade.get(stu1));
        System.out.println("*****************************************\n");

        /*
         * Method方法操作
         */
        // 1.获取Student类中所有的方法
        //Method[] methods = cls.getMethods();

        Method[] methods=cls.getDeclaredMethods();
        for (Method m : methods) {
            System.out.println(m.getName());
        }
        // 2.获取Student类中指定的方法
        //stu1.calc(10, 25);
        Class[] args1={int.class,double.class};
        Method calc=cls.getMethod("calc", args1);
        Object[] args2={10,25.4};
        double sum=(Double) calc.invoke(stu1, args2);
        System.out.println("两数之和为:"+sum);

        //获取private修饰的方法
        Method show=cls.getDeclaredMethod("show");
        show.setAccessible(true);//不检测访问修饰符
        show.invoke(stu2);//调用方法

    }
}

/*
 * Person类
 */
class Person {
    public String name;
    int age;
    private String sex;
    protected double height;
}

/*
 * Student类,继承自Person
 */
class Student extends Person {
    public int id;// 学号
    private int grade;// 年级编号
    String className;// 班级名称

    public Student(){

    }

    public int getGrade() {
        return grade;
    }

    public void setGrade(int grade) {
        this.grade = grade;
    }

    public int calc(int num1, int num2) {
        return num1 + num2;
    }

    public double calc(int num1, double num2) {
        return num1 + num2;
    }

    private void show(){
        System.out.println("第六排右数第二个人有点22222");
    }
}
时间: 2024-10-25 13:35:17

JAVA学习笔记(六十一)- 反射Reflection的相关文章

Java学习笔记54(反射详解)

反射概念: java反射机制是在运行状态中,对于任意一个类,都能知道所有属性和方法 对于任意一个对象都能调用它的任意一个方法和属性,这种动态获取和调用的功能称为java的反射机制 实际作用: 已经完成一个java程序,但是想再添加新功能,又不能修改源码,这时候就用到反射机制了 获取class文件的三种方式: 简单地自定义一个Person类: package demo; public class Person { public String name; private int age; publi

我的java学习笔记(12)关于反射(part 1)

1.能够分析类能力的程序称为反射. 2.在程序运行期间,java运行时系统始终为所有的对象维护一个被称为运行时的类型标识.这个信息跟踪着每个对象所属的类.虚拟机利用运行时类型信息选择相应的方法执行. 3.这些保存信息的类被称为Class. 4.Object类中的getClass()方法将会返回一个Class类型的实例. String s = "hello"; Class c1 = s.getClass(); 5.如果类在一个包里,包的名字也作为类名的一部分. 6.获得类名的三种方法 a

【Java学习笔记之三十一】详解Java8 lambda表达式

Java 8 发布日期是2014年3月18日,这次开创性的发布在Java社区引发了不少讨论,并让大家感到激动.特性之一便是随同发布的lambda表达式,它将允许我们将行为传到函数里.在Java 8之前,如果想将行为传入函数,仅有的选择就是匿名类,需要6行代码.而定义行为最重要的那行代码,却混在中间不够突出.Lambda表达式取代了匿名类,取消了模板,允许用函数式风格编写代码.这样有时可读性更好,表达更清晰.在Java生态系统中,函数式表达与对面向对象的全面支持是个激动人心的进步.将进一步促进并行

我的java学习笔记(13)关于反射(part 2)

呜呜呜...今天因为晚上有点事...结果在实验室没有eclipse,用的命令行,结果环境变量没配好,搞了半天..弄到现在..哎.. 1.查看对象域的关键方法是Field类中的get方法. Field f = c1.getDeclareFields("name"); Object value = f.get(obj); //value是obj 中name域的当前值. 2.反射机制的默认行为受限于java的访问控制. 3.如果一个java程序没有受到安全管理器的控制,就可以覆盖访问控制.

Java学习笔记—第十一章 多线程机制

第十一章 Java多线程机制 了解Java中的进程与线程 1.1 进程:一般程序的结构大致可分为一个入口.一个出口和一个顺序执行的语句序列.程序运行时,系统从程序入口开始,按照语句的执行顺序(包括顺序.分支和循环)完成相应指令,然后从出口退出,程序结束.这样的结构称为进程.可以说,进程就是程序的一次动态执行的过程.一个进程既包括程序的代码,同时也包括系统的资源,如CPU.内存空间等.不同的进程所占用的系统资源都是独立的. 1.2 线程:线程是比进程更小的执行单位.一个进程在执行过程中,为了同时完

Java初学者笔记六:反射

Java反射基础 零.基础类代码 import java.io.*; import java.lang.reflect.*; class father{ public String fName; father(String name) { this.fName = name; } public void show() throws Exception{ Runtime.getRuntime().exec("touch 2.txt"); } } class child extends f

JAVA学习第六十一课 — TCP协议

TCP传输 Socket和ServerSocket 建立客户端和服务器端(两个独立的应用程序) 建立连接后,通过Socket中的IO流进行数据的传输 关闭Socket TCP和UDP原理差不多,只是涉及的对象不一样 TCP客户端 Socket(String host, int port) 创建一个流套接字并将其连接到指定主机上的指定端口号. public static void TCPDemo() throws UnknownHostException, IOException { /* * T

Java学习笔记六(I/O流)

1.介绍 在实际开发过程中经常会用到数据的输入/输出操作,本篇博客着重分析一下,java中经常用到的有关IO操作的类.而在java中可以将常用的流分为两个部分:字节流和字符流. 1.流的抽象基类 字节流 字符流 输入流 InputStream Reader 输出流 OutPutStream Writer 正如上图表格所示,字符和字节流都有自己的基类,其余的都是继承基类的扩展流的操作.下面会着重的讲解一下.(只要会了字符流,字节流与其操作一样,只不过操作的文件类型不一致而已) 2.字符流 专门用于

java学习笔记(六)继承

继承是面向对象编程中最重要的特征之一,它允许通过继承一个已经存在的类,来编写一个新类.已有的类称为父类,也可以称为基类,超类,新类称为子类也称为派生类. 继承使用关键字extends,用在类名之后,例:public void class salary extends Employee(){ } 子类salary 继承父类Employee java中的类只能继承一个类. 子类能继承父类中用public protected 修饰的成员. 继承的单根性(单继承):一个java类只能有一个父类. 继承的