首页 > 编程语言 >Java反射

Java反射

时间:2024-07-20 21:41:32浏览次数:14  
标签:反射 Java String weight System println public name

java是面向对象的编程语言,对象,是一种具体的概念
类:类是对具有相同特征或属性,具有相同行为能力的一类事物的描述或称呼
对象:对象是这一类事物带有属性值,具有具体行为的个体或实例

面向对象编程的语言

package test;

//定义一个类
public class Phone {
    
    //添加一些属性
    public String name;
    public double weight;
    
    //无参构造器
    public Phone(){
    }
    //有参构造器
    public Phone(String name,double weight){
        this.name = name;
        this.weight = weight;
    }

    //写入一些方法
    public void dianyuan(){
        System.out.println("开机");
    }

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

    public String getName() {
        return name;
    }

    public void setWeight(double weight) {
        this.weight = weight;
    }

    public double getWeight() {
        return weight;
    }
}


Java中的反射机制

反射允许对封装类的字段,方法和构造函数的信息进行编程访问。

反射允许对成员变量,成员方法和构造方法的信息进行编程访问
通俗点说,是从类里面拿东西,把成员变量,成员方法和构造方法获取出来(获取其所有信息)
获取是从class字节码文件中去获取的

反射获取class对象的三种方式

  1. Class.forName("全类名");
  2. 类名+class
  3. 对象+getClass();

image.png
三种方式分别对应三个阶段

public class phone_tes2 {
    public static void main(String[] args) throws Exception{
        //获取类
        //1.使用class.forName()方法
        //最为常用的
        Class p = Class.forName("test.Phone");
        
        //2.使用类的class方法
        //一般更多的是当前参数进行传递
        Class p3 = Phone.class;

        //3.使用实例化对象的getClass()方法
        //当我们已经有了这个类的对象时才使用
        Phone p1 = new Phone();
        Class p2 = p1.getClass();
    }
}

反射获取构造方法

image.png

package test;

public class Phone {
    public String name;
    public double weight;
    //无参构造器
    public Phone(){
    }
    //有参构造器
    public Phone(String name){
        this.name = name;
    }

    protected Phone(double weight){
        this.weight = weight;
    }

    private Phone(String name,double weight){
        this.name = name;
        this.weight = weight;
    }
}
package test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Parameter;

public class phone_tes3 {
    public static void main(String[] args) throws Exception{
        //1.获取class字节码文件对象
        Class clazz = Class.forName("test.Phone");

        //2.获取public构造方法
        Constructor[] cons = clazz.getConstructors();
        for (Constructor con : cons) {
            System.out.println(con);
        }

        //2.获取所有构造方法
        Constructor[] cons2 = clazz.getDeclaredConstructors();
        for (Constructor con : cons2) {
            System.out.println(con);
        }

        //3.获取单个构造方法
        Constructor con3 = clazz.getDeclaredConstructor(double.class);
        System.out.println(con3);

        Constructor con4 = clazz.getDeclaredConstructor(String.class,double.class);
        //获取权限修饰符对应的数字
        int modifiers = con4.getModifiers();
        System.out.println(modifiers);

        Parameter[] parameters = con4.getParameters();
        for (Parameter parameter : parameters) {
            System.out.println(parameter);
        }

        //暴力反射:临时取消权限校验(即可用私有的构造方法创建对象)
        con4.setAccessible(true);
        Phone iphone = (Phone) con4.newInstance("enya", 88891);
        System.out.println(iphone);


    }
}

image.png

反射获取成员变量

image.png

package test2;

public class Student {
    private String name;
    private int age;
    public String gender;

    public Student(){
    }
    public Student(String name,int age,String gender){
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    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;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }
}

package test2;

import java.lang.reflect.Field;

public class ste_tes1 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        //1.获取class字节码文件的对象
        Class clazz = Class.forName("test2.Student");

        //2.获取所有的成员变量
        Field[] Fields = clazz.getDeclaredFields();
        for (Field field : Fields) {
            System.out.println(field);
        }

        //获取单个成员变量
        Field name = clazz.getDeclaredField("name");
        System.out.println(name);

        //获取权限修饰符
        int modifiers = name.getModifiers();
        System.out.println(modifiers);

        //获取成员变量名
        String name1 = name.getName();
        System.out.println(name1);

        //获取成员变量数据类型
        Class<?> type = name.getType();
        System.out.println(type);

        //获取成员变量记录的值
        Student s = new Student("ENYA",19,"女");
        name.setAccessible(true);
        String value = (String) name.get(s);
        System.out.println(value);

        //修改对象里面记录的值
        name.set(s,"Iris");
        System.out.println(s.getName());

    }
}

image.png

反射获取成员方法

image.png

package test2;

import java.io.IOException;

public class Student {
    private String name;
    private int age;


    public Student(){
    }
    public Student(String name,int age,String gender){
        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;
    }

    public void sleep(){
        System.out.println("睡觉");
    }
    private String eat(String somethimg)throws IOException,NullPointerException,ClassCastException {
        System.out.println("在吃"+somethimg);
        return "yummy!!";
    }
}

package test2;

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

public class ste_tes2 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //1.获取class字节
        Class clazz = Class.forName("test2.Student");

        //2.获取所有方法对象(包含父类中所有的公共方法)
//        Method[] methods = clazz.getMethods();
//        for (Method method : methods) {
//            System.out.println(method);
//        }

        //2.获取所有方法对象(不能获取父类的,但是可以获取本类中私有的方法)
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method);
        }

        //获取指定的单一方法
        Method m = clazz.getDeclaredMethod("eat", String.class);
        System.out.println(m);

        //获取方法的修饰符
        int modifiers = m.getModifiers();
        System.out.println(modifiers);

        //获取方法的名字
        String name = m.getName();
        System.out.println(name);

        //获取方法的形参
        Parameter[] parameters = m.getParameters();
        for (Parameter parameter : parameters) {
            System.out.println(parameter);
        }

        //获取方法抛出的异常
        Class<?>[] exceptionTypes = m.getExceptionTypes();
        for (Class<?> exceptionType : exceptionTypes) {
            System.out.println(exceptionType);
        }

        //方法运行
        Student s = new Student();
        m.setAccessible(true);
        //参数一表示方法的调用者,参数二表示在调用方法的时候传递的实际参数
        Object result = m.invoke(s, "汉堡包");
        System.out.println(result);

    }
}

image.png
image.png

练习

保存信息

对于任意一个对象,都可以把对象所有的字段名和值,保存到文件中去
image.png

package test3;

public class Phone {
    public String name;
    public double weight;
    //无参构造器
    public Phone(){
    }
    //有参构造器
    public Phone(String name){
        this.name = name;
    }

    protected Phone(double weight){
        this.weight = weight;
    }

    Phone(String name, double weight){
        this.name = name;
        this.weight = weight;
    }
    public void dianyuan(){
        System.out.println("开机");
    }

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

    public String getName() {
        return name;
    }

    public void setWeight(double weight) {
        this.weight = weight;
    }

    public double getWeight() {
        return weight;
    }
}


package test3;

import java.io.IOException;

public class Student {
    private String name;
    private int age;
    public String gender;


    public Student(){
    }
    public Student(String name, int age, String gender){
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    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;
    }

    public void sleep(){
        System.out.println("睡觉");
    }
    private String eat(String somethimg)throws IOException,NullPointerException,ClassCastException {
        System.out.println("在吃"+somethimg);
        return "yummy!!";
    }
}

package test3;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;

public class demo1 {
    public static void main(String[] args) throws IllegalAccessException, IOException {

        Student s = new Student("enya",19,"女");
        Phone t = new Phone("apple",1987);

        saveobject(s);

    }

    //把对象里面所有的成员变量名和值保存到本地文件中
    public static void saveobject(Object obj) throws IllegalAccessException, IOException {
        //1.获取字节码文件的对象
        Class clazz = obj.getClass();

        //创建IO流
        BufferedWriter bw = new BufferedWriter(new FileWriter("demo1\\a.txt"));

        //2.获取所有的成员变量
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            //获取成员变量的名字
            String name = field.getName();
//            System.out.println(name);
            //获取成员变量的值
            Object value = field.get(obj);
            //写入数据
            bw.write(name + "=" + value);
            bw.newLine();

        }
        bw.close();

    }
}

运行结果:

name=enya
age=19
gender=女

跟配置文件结合动态创建

反射可以跟配置文件结合的方式,动态创建对象,并调用方法

package test4;

public class Phone {
    public String name;
    public double weight;
    //无参构造器
    public Phone(){
    }
    //有参构造器
    public Phone(String name){
        this.name = name;
    }

    protected Phone(double weight){
        this.weight = weight;
    }

    Phone(String name, double weight){
        this.name = name;
        this.weight = weight;
    }
    public void dianyuan(){
        System.out.println("手机正在开机");
    }

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

    public String getName() {
        return name;
    }

    public void setWeight(double weight) {
        this.weight = weight;
    }

    public double getWeight() {
        return weight;
    }
}


package test4;

import java.io.IOException;

public class Student {
    private String name;
    private int age;
    public String gender;


    public Student(){
    }
    public Student(String name, int age, String gender){
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    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;
    }

    public void sleep(){
        System.out.println("学生正在睡觉");
    }

}

classname=test4.Phone
method=dianyuan
package test4;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

public class demo {
    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
    /*
        反射可以跟配置文件结合的方式,动态的创建对象,并调用方法
     */

        //1.读取配置文件中的信息
        Properties prop = new Properties();
        FileInputStream fis = new FileInputStream("demo1\\prop.properties");
        prop.load(fis);
        fis.close();
        System.out.println(prop);

        //2.获取全类名和方法名
        String classname = (String) prop.get("classname");
        String methodname = (String) prop.get("method");
        System.out.println(classname);
        System.out.println(methodname);

        //3.利用反射创建对象并运行方法
        Class clazz = Class.forName(classname);
//        Method m = clazz.getDeclaredMethod(methodname);
//        Student s = new Student();
//        m.setAccessible(true);
//        Object o = m.invoke(s);
//        System.out.println(o);

        //获取构造方法
        Constructor con = clazz.getDeclaredConstructor();
        Object o = con.newInstance();
        System.out.println(o);

        //获取成员变量并运行
        Method method = clazz.getDeclaredMethod(methodname);
        method.setAccessible(true);
        method.invoke(o);

    }
}

image.png

小结

image.png

标签:反射,Java,String,weight,System,println,public,name
From: https://www.cnblogs.com/1nnya/p/18313841

相关文章

  • Java入门知识
    Java特性和优势简单性面向对象可移植性高性能分布式动态性多线程安全性健壮性Java三大版本JavaSE:标准版(桌面程序,控制开发....)JavaME:嵌入式开发(手机,小家电....)JavaEE:E企业级开发(web端,服务器开发...)JDK、JRE、JVMJDK:JavaDevelopmentKitJRE:JavaRuntimeE......
  • java学习3
    这周的话想直接通过一个项目去进行学习,但是效果没有想象中的那么大好,我在网上抄了一个还算简单的图书管理系统,能连接数据库,将数据导入数据库。不像之前输入的数据结束程序就没了。但是只能增,没有删,改,查抄这个系统的时候出现了很多我不认识的技术栈,这时候我意识到一个完整项目是......
  • 暑假学习Java第三周
    通过本周的学习我认识到了自己有很多的不足与优点,优点是我能够把问题细化逐步分析,缺点是我的意志力不够坚定。我还了解了Java的三大特性包括:面向对象:Java是一种面向对象的编程语言,它允许程序员定义一系列关于对象和类的概念,并将这些概念作为编程的基本单位。在实际内容中,面向对象......
  • 推荐Java 杠把子技能库【Advanced Java】
    "AdvancedJava"通常是指Java编程语言及其相关技术在高级或专业层面的应用。它涵盖了Java标准版(JavaSE)、Java企业版(JavaEE,现在称为JakartaEE)和Java平台微服务版(JavaME)中的高级概念和技术。在软件开发领域,“AdvancedJava”可以指代一系列主题,包括但不限于:多线程和并发:处理线......
  • java报告第三周总结
    本周的学习内容为整个第四章的内容,学习中感觉知识点既多又杂,故在总结时尽量选用重要的或高度概括的知识点。面向对象语言特点:封装性、继承、多态类:类是java程序的基本要素,一个java程序就是由若干个类所构成,类是java语言中最重要的数据类型,类声明的变量被称为对象变量类、对象、......
  • 学Java的第三周(循环)
    在Java中,循环是指重复的操作或需要重复执行的代码。任何循环都需要有循环开始或结束的条件,如果循环无休止地进行,则称之为死循环。一个完整的循环结构必须满足以下特征:(1)循环有开始或结束的条件。(2)需要重复执行的操作或代码,称为循环操作或循环体。Java中while循环是-种非......
  • java3
    我学习了java的方法,在c++中相当于函数Java方法是面向对象编程中最核心的概念之一,它允许我们在程序中封装一部分代码,以便在需要时重复使用。方法的声明语法:访问修饰符返回类型方法名(参数列表){//方法体}访问修饰符:public:公有的,任何地方都能访问。protected:受保护的,同......
  • 【JavaScript】王者荣耀英雄卡牌动画切换效果
    动画呈现  代码详解<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"/><metaname="viewport"content="width=device-width,initial-scale=1.0"/><title>王者英雄卡牌......
  • JAVA零基础小白自学日志——第二十天
    文章目录1.为什么我们需要抽象类2.抽象类3.我们一起来抽象(有病,象也没招你)[1].抽象方法[2].为什么我们先说抽象方法呢?[3].需要明确的4.关于Object的题外话今日提要:抽象类你以为这几天看的内容都是多态?你太小看Java了,咱们来看看真正多态的入门1.为什么我们需要抽......
  • Java学习路线图-进阶版
    好看的皮囊千篇一律、有趣的灵魂万里挑一文章持续更新,可以微信搜索【小奇JAVA面试】第一时间阅读,回复【资料】获取福利,回复【项目】获取项目源码,回复【简历模板】获取简历模板,回复【学习路线图】获取学习路线图。还有机会获得内推名额。文章目录一、Java基础二、MyS......