当前位置: 首页 > news >正文

java 利用反射创建对象

创建对象:

1、使用Class对象的newInstance()方法创建该Class对象的实例,此时该Class对象必须要有无参数的构造方法。

2、使用Class对象获取指定的Constructor对象,再调用Constructor的newInstance()方法创建对象类的实例,此时可以选择使用某个构造方法。如果这个构造方法被私有化起来,那么必须先申请访问,将可以访问设置为true;

 

Eg:

最简单的:

package junereflect624;

 

class User{

    /*private User(){//将默认的构造方法私有化的话就不可以再创建对象,两种方法都是这样

    }*/

    public String toString() {

        return "User对象创建成功!";

    }

}

 

public class NewInstanceDemo6 {

    public static void main(String[] args) throws Exception {

        //传统方式创建对象

         System.out.println(new User());

         

         //使用反射的方式

         Class<User> c = User.class;

         User u = c.newInstance();(直接newInstance的话必须保证默认的构造方法正常存在,也就是没有被私有化!这是前提条件)

         System.out.println(u);

    }

}

 

 

复杂点的:更强大的第二种:

 

使用指定构造方法来创建对象:

获取该类的Class对象。

利用Class对象的getConstructor()方法来获取指定的构造方法。

调用Constructor的newInstance()方法创建对象。

 

AccessibleObject对象的setAccessible(boolean flag)方法,当flag为true的时候,就会忽略访问权限(可访问私有的成员)

其子类有Field, Method, Constructor;

若要访问对象private的成员?

在调用之前使用setAccessible(true),

       Xxx x = getDeclaredXxxx();//才能得到私有的类字段.

 

总结步骤:

 

  1. 1.        获取该类的Class对象。
  2. 2.        利用Class对象的getConstructor()方法来获取指定的构造方法。
  3. 3.        申请访问(设置为可访问)
  4. 4.  调用Constructor(构造方法)的newInstance()方法创建对象。

 

例子

package junereflect624;

 

import java.lang.reflect.Constructor;

 

class Per{

    private String name;

    private int age;

    private Per(){   

    }

    private Per(String name){

    }

    public String toString() {

        return "对象!!!";

    }

}

 

public class NewInstanceDemo7 {

    public static void main(String[] args) throws Exception {

        Class<Per> c = Per.class;

        //System.out.println(c.newInstance());;//证明利用无参的可以

       

        先获得需要被调用的构造器(private 修饰的构造方法)

        Constructor<Per> con = c.getDeclaredConstructor();//调用默认的,什么都不要写

        System.out.println(con);//private junereflect624.Per()

        /*con = c.getDeclaredConstructor(String.class);获取指定的构造方法

        System.out.println(con);//private junereflect624.Per(java.lang.String)*/     

        //现在只需要执行这个构造器,

        /**

         *  T newInstance(Object... initargs)

                使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。

         */

       

        //私有的成员是受保护的,不能直接访问

        //若要访问私有的成员,得先申请一下

        con.setAccessible(true);//允许访问

        Per p = con.newInstance();//成功,通过私有的受保护的构造方法创建了对象

        System.out.println("无参构造方法"+p);

       

        con = c.getDeclaredConstructor(String.class);

        System.out.println(con);//private junereflect624.Per(java.lang.String)

           

        con.setAccessible(true);//允许访问

        p = con.newInstance("liuzhao");//成功,通过私有的受保护的构造方法创建了对象

        System.out.println("String构造方法"+p);

    }

}

备注:对于此时的话,单例模式就不再安全了!反射可破之!!

 

 

 

验证:对于枚举而言,反射依然没有办法重新创建对象

对于枚举,安全!

 

package junereflect624;

 

import java.lang.reflect.Constructor;

 

enum Color{

    RED,BLUE,GREEN;

    private Color(){

    }

}

 

public class EnumDemo8 {

    public static void main(String[] args) throws Exception {

        Class<Color> c = Color.class;

       

        Constructor<Color> con = c.getDeclaredConstructor();//(错误在这一行发生,就是说对枚举而言这种方法连构造器都获得不了,)编译可以通过,但是运行就通不过了!

        Color co = (Color) con.newInstance();

        System.out.println(co);//失败,证明对枚举而言不行,所以枚举的单例模式更加安全

        System.out.println(c.isEnum());//true是枚举

    }

}

转载于:https://www.cnblogs.com/fanweisheng/p/11136819.html

相关文章:

  • Blend Tree动画混合
  • 【转移通知】博客停用通知
  • shader——SetGlobalTexture
  • 【随笔】新浪微博分析
  • 弧微分公式推导
  • C算法--入门篇(1)查找元素
  • uv的反转
  • (转)四层和七层负载均衡的区别
  • HDR Scattering and Tone Mapping
  • RenderTexutre在FrameDebugger中查看
  • 第一篇blog来啦 - 君子坦荡荡
  • Blend模式混合公式
  • 一周的收获
  • 分布式Java应用:基础与实践
  • 鱼竿弯曲曲线
  • ES6指北【2】—— 箭头函数
  • JavaScript-如何实现克隆(clone)函数
  • [Vue CLI 3] 配置解析之 css.extract
  • [译] 理解数组在 PHP 内部的实现(给PHP开发者的PHP源码-第四部分)
  • 《微软的软件测试之道》成书始末、出版宣告、补充致谢名单及相关信息
  • 【翻译】Mashape是如何管理15000个API和微服务的(三)
  • 4个实用的微服务测试策略
  • Android Studio:GIT提交项目到远程仓库
  • Docker容器管理
  • Git同步原始仓库到Fork仓库中
  • GraphQL学习过程应该是这样的
  • Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!
  • Mocha测试初探
  • python学习笔记-类对象的信息
  • SegmentFault 技术周刊 Vol.27 - Git 学习宝典:程序员走江湖必备
  • ubuntu 下nginx安装 并支持https协议
  • Vue 重置组件到初始状态
  • Vue.js源码(2):初探List Rendering
  • 高度不固定时垂直居中
  • 给github项目添加CI badge
  • 机器人定位导航技术 激光SLAM与视觉SLAM谁更胜一筹?
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 排序算法学习笔记
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 入门级的git使用指北
  • 手写一个CommonJS打包工具(一)
  • 推荐一个React的管理后台框架
  • 小程序测试方案初探
  • 继 XDL 之后,阿里妈妈开源大规模分布式图表征学习框架 Euler ...
  • #13 yum、编译安装与sed命令的使用
  • (Redis使用系列) SpringBoot 中对应2.0.x版本的Redis配置 一
  • (ros//EnvironmentVariables)ros环境变量
  • (二)linux使用docker容器运行mysql
  • (非本人原创)史记·柴静列传(r4笔记第65天)
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (转)GCC在C语言中内嵌汇编 asm __volatile__
  • (转)母版页和相对路径
  • (转贴)用VML开发工作流设计器 UCML.NET工作流管理系统
  • **PHP二维数组遍历时同时赋值
  • .Net 垃圾回收机制原理(二)