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. 获取该类的Class对象。
- 2. 利用Class对象的getConstructor()方法来获取指定的构造方法。
- 3. 申请访问(设置为可访问)
- 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是枚举
}
}
java 利用反射创建对象的更多相关文章
- java利用反射调用类的某个方法
java利用反射机制 可以动态调用某个类的某个方法,在 扩展系统功能或提供对外接口时经常用的到. 代码如下: 打印类Print.java package com.test.reflct; /** * ...
- java利用反射获取类的属性及类型
java利用反射获取类的属性及类型. import java.lang.reflect.Field; import java.math.BigDecimal; import java.util.Map ...
- 【转】Java利用反射机制访问私有化构造器
Java利用反射机制访问私有化构造器 博客分类: java 我们都知道,当一个类的构造方法被设为私有的时候(private),在其他类中是无法用new来实例化一个对象的. 但是有一种方法可以把带有 ...
- java利用反射机制判断对象的属性是否为空以及获取和设置该属性的值
1.java利用反射机制判断对象的属性是否为空: Map<String,String> validateMap = new LinkedHashMap<String, String& ...
- Java利用反射取得类的所有信息
Java中可以利用反射获取类的名称.构造函数.属性.方法.也就是说可以通过反射可以取得类的所有信息(不管该成员是否封装为private). 如有下面的Dept类定义: package org.lyk. ...
- java利用反射访问类的私有(private)属性及方法
Java语言中,在一个类中,为了不让外界访问到有的属性和方法,通常将其设置为private,用正常的方式(对象名.属性名,对象名.方法名)将无法访问此属性与方法,但有没有其他方法可以访问呢?答案是有的 ...
- Java利用反射排序
前言 Java为我们提供了几种排序得方法,比如Arrays和Collections类,但是前提是数组或者集合中的元素都必须实现Comparable接口,基本的数据类型都已经实现了Comparable接 ...
- Java——利用反射机制将表单数据自动填充到JavaBean中
以一个案例介绍反射机制的一种常见的使用场景,以及具体实现. 1.本文案例 在编写Java Web应用程序时,使用表单提交数据是一个必不可少的环节,后台对于前台使用表单提交的数据需要能够从请求中解析,并 ...
- java利用反射交换两个对象中的字段相同的字段值
有时候我们的两个对象字段都是一样的,只有极少的区别,想要把一个对象字段的值,赋值给另外一个对象值 然后传给另外一个方法使用,但是这个字段太多,一个一个的复制太过繁琐. 这时候利用反射解决这个问题. c ...
随机推荐
- NOIP模拟 17.8.14
NOIP模拟17.8.14 (天宇哥哥考察细心程度的题) [样例解释]如果删去第一个 1:在[3,1,2]中有 3 个不同的数如果删去 3:在[1,1,2]中有 2 个不同的数如果删去第二个 1:在[ ...
- Leetcode4.Median of Two Sorted Arrays两个排序数组的中位数
给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 . 请找出这两个有序数组的中位数.要求算法的时间复杂度为 O(log (m+n)) . 你可以假设 nums1 和 nums2 不同 ...
- Linux常用命令3 文件搜索命令
文件搜索非常占用资源,所以尽量不要使用这个命令 避免少用该命令最好的方式是设置好文件夹结构,文件不要乱放 1.文件搜索命令:find 命令名称:find 所在路径:/bin/find 执行权限:所有用 ...
- 【OI】二分图最大匹配
所谓二分图,是可以分为两个点集的图: 所谓二分图最大匹配,是两个点集之间,每两个不同点集的点连接,每个点只能连一个点,最大的连接数就是最大匹配. 如何解最大匹配,需要用到匈牙利算法. 另:本文写了很多 ...
- JavaScript--函数中()的作用
在函数中参数是函数的时候:function a(函数名) 与 function a(函数名()) 的区别: // 在函数里面() 是一个编组和立即执行的功能 /** * function autoPl ...
- 笔记:在 Windows 10 WSL Ubuntu 18.04 安装 Odoo12 (2019-06-09)
笔记:在 Windows 10 WSL Ubuntu 18.04 安装 Odoo12 原因 为了和服务器一样的运行环境. 使用 Ubuntu 运行 Odoo 运行更快. 方便使用 Windows 10 ...
- python 终端编码
- 【NS2】新协议的添加示例(转载)
1. 下表显示了 NS2 和 TCP/IP.OSI七层网络结构的大致对应关系(这个表很有好处哦) TCP NS2 OSI 应用层 应用层 应用层 表示层 会话 ...
- nodeJs学习-05 案例:http/fs/querystring/url
const http = require('http'); const fs = require('fs'); const querystring = require('querystring'); ...
- SDUT-3335_数据结构实验之栈与队列八:栈的基本操作
数据结构实验之栈与队列八:栈的基本操作 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 堆栈是一种基本的数据结构.堆栈具 ...