首页 > 编程语言 >java反射前及反射后类的实例化等操作

java反射前及反射后类的实例化等操作

时间:2022-09-22 14:47:14浏览次数:54  
标签:反射 p1 java String 化等 age Person public name

什么是反射?

java的反射就是利用Class对象在运行阶段获取任何类的各种信息,从而可以实例化对象,访问对象的方法和属性的这么一种机制。

什么时候使用反射?

在某种业务场景下,无法在编写源代码时就确定要用哪个类的对象,需要根据用户的行为做出动态地响应。这个时候就可以考虑用反射机制在运行阶段根据用户的输入来判断到底实列化哪个类的对象,并调用该对象的方法等操作。例如:在美团点外卖后付款的界面,用户可以选择多种付款方式(微信、支付宝、银行卡等等)。假如每种支付方式都对应一个类,而在编写源代码的时候我们不能确定使用那种付款方式,为了代码的可扩展性,也不想用分支结构并为每个支付方式的类创建对象。那么,这种情况下就可以考虑用反射机制,用户点击哪个支付方式,程序就在运行阶段创建哪个支付方式类的对象完成支付。

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

import org.junit.Test;

public class ReflectionTest { 
    // 反射之前对Person的操作
    @Test
    public void test1() {
        // 1.创建Person类的对象
        Person p1 = new Person("Tom", 12);
        // 2.通过对象,调用其内部的属性、方法
        p1.age = 10;
        p1.setName("Jack");
        System.out.println(p1.toString());
        p1.show();
        // 在Person类外部,不可以通过Person类的对象调用其内部私有结构
        // 比如:name、showNation()以及私有的构造器
    }
// 反射之后对Person的操作 @Test public void test2() throws Exception { Class clazz = Person.class; // 1.通过反射,创建Person类的对象 Constructor cons = clazz.getConstructor(String.class, int.class); // 通过构造器创建对象(用多态的形式赋给Object) Object obj = cons.newInstance("Tom", 12); System.out.println(obj.toString()); Person p = (Person)obj; System.out.println(p.toString()); // 2.通过反射,调用对象指定的属性、方法 // 调用属性 Field age = clazz.getDeclaredField("age"); age.set(p, 10); System.out.println(p.toString()); // 调用方法 Method show = clazz.getDeclaredMethod("show"); show.invoke(p); System.out.println("************"); // 通过反射,可以调用Person类的私有结构的。比如:私有的构造器、方法、属性 // 调用私有的构造器 Constructor cons1 = clazz.getDeclaredConstructor(String.class); cons1.setAccessible(true); Person p1 = (Person)cons1.newInstance("Jerry"); System.out.println(p1.toString()); // 调用私有的属性 Field name = clazz.getDeclaredField("name"); name.setAccessible(true); name.set(p1, "Jack"); System.out.println(p1.toString()); // 调用私有的方法 Method showNation = clazz.getDeclaredMethod("showNation", String.class); showNation.setAccessible(true); //showNation.invoke(p1, "中国");// 相当于p1.showNation("中国"); String nation = (String)showNation.invoke(p1, "中国");// 相当于String nation = p1.showNation("中国"); System.out.println(nation); Method show1 = clazz.getDeclaredMethod("show1"); show1.setAccessible(true); show1.invoke(p1); } } class Person { // 属性 private String name; public int age; // 构造器 public Person() {} private Person(String name) { this.name = name; } public Person(String name, int age) { this.name = name; this.age = age; } // get,set方法 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 show() { System.out.println("我是一个人"); } private void show1() { System.out.println("我是一个人"); } private String showNation(String nation) { System.out.println("我的国籍是:" + nation); return nation; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } }

 

反射是否破坏了面向对象的封装性?

反射并没有破坏面向对象的封装性。因为通过反射机制获取到的带权限修饰符的方法和属性都依然遵照权限修饰符限定的访问方式。除非调用setAccessible(true)方法来抑制java访问权限检查,从而达到可以随意访问的效果。但是利用setAccessible(true)是一种暴力方式,不安全。开发人员一般不会用这种方式损害自己代码的封装性。

 

标签:反射,p1,java,String,化等,age,Person,public,name
From: https://www.cnblogs.com/lxh-daniel/p/16719175.html

相关文章

  • 反射
    java是一门编译型语言;与之对应的称之为解释性(JavaScript,python)。编译型语言在编写完源代码后必须要编译之后才能够运行。解释性语言内置了解释器,程序一边解释,一边执行。ja......
  • Java中使用Hutool的ExecutorBuilder实现自定义线程池
    场景Java中ExecutorService线程池的使用(Runnable和Callable多线程实现):https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/126242904SpringBoot+Lombok+Bui......
  • java学习笔记25
    java数组数组的定义数组是相同类型数据的有序集合。数组描述的是相同类型的若干个数据按照一定的先后次序排列组合而成。其中,每一个数据称作一个数组元素,每个数组元素......
  • java学习笔记26
    java数组数组的使用普通的for循环publicclassDemo03{  publicstaticvoidmain(String[]args){    int[]arrays={1,2,3,4,5};    //打印......
  • java - @Async 具体使用
    1.开启  @Async异步能力添加注解 @EnableAsync,可以放在启动类上,也可以在任意配置类上,因为我是需要配置自定义线程池,因此放在配置类上importorg.springframework.c......
  • JAVA常用工具类
    java开发常用工具类java正则表达式的匹配包括:邮箱,手机,姓名,昵称,身份证号,银行卡号等;生成6位随机数;对url中字符串进行编码和解码;获取客户端ip地址;获取系统当前时间;生......
  • java中String的常用方法
    1、length()字符串的长度例:charchars[]={'a','b'.'c'};Strings=newString(chars);intlen=s.length();2、charAt()截取一个字符例:charch......
  • JAVA中容器设计的进化史:从白盒到黑盒,再到跻身为设计模式之一的迭代器
    大家好,又见面了。在我们的项目编码中,不可避免的会用到一些容器类,我们可以直接使用List、Map、Set、Array等类型。当然,为了体现业务层面的含义,我们也会根据实际需要自行封......
  • Java SE 19 新增特性
    JavaSE19新增特性作者:Grey原文地址:博客园:JavaSE19新增特性CSDN:JavaSE19新增特性源码源仓库:Github:java_new_features镜像仓库:GitCode:java_new_features......
  • JavaScript 函数定义
    JavaScript使用关键字 function 定义函数。函数可以通过声明定义,也可以是一个表达式。函数声明:函数声明后不会立即执行,会在我们需要的时候调用到。functionmyFunct......