通过反射创建对象

  • 通过反射创建对象有两种方式,一种通过Class对象的newInstance()方法,一种是获取到Class对象的Constructor后,再调用newInstance()方法,前者要求对应类有默认的无参构造器,后者则可以用特定的的构造器
  • 前者用得较多,很多Java EE框架中都用xml配置文件信息来创建Java对象
  • 示例:
package testpack;

import java.lang.reflect.Constructor;

public class Test1  {
public static void main(String[] args)throws Exception{
Class clazz=A.class;
Object obj1=clazz.newInstance(); //调用Class对象的newInstance()方法,用默认构造器创建
System.out.println(obj1); //输出:[name= default , age= 0 ] Constructor c=clazz.getConstructor(String.class,int.class);
Object obj2=c.newInstance("Java",18); //调用Constructor的newInstance()方法用特定构造器创建
System.out.println(obj2); //输出:[name= Java , age= 18 ]
}
}
class A{
private String name;
public int age;
A(){
name="default";
age=0;
}
public A(String name,int age){
this.name=name;
this.age=age;
}
public String toString(){
return "[name= "+name+" , age= "+age+" ]";
}
}

通过反射调用方法

  • 获得一个Class对象的Method对象后,通过调用invoke(Object obj,Object...args)方法就可以调用特定对象的该方法了,obj就是该特定对象,args是要传入的实参
  • 见示例:
package testpack;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method; public class Test1 {
public static void main(String[] args)throws Exception{
Class clazz=A.class; //获取类A的Class对象
Constructor c=clazz.getConstructor(String.class,int.class); //获取构造方法
Object obj=c.newInstance("C++",28); //通过反射创建对象
Method m=clazz.getMethod("show",null); //获取名为show,无参的方法
m.invoke(obj,null); //在obj上调用show方法,传入参数为null,就无实参
}
}
class A{
private String name;
public int age;
A(){
name="default";
age=0;
}
public A(String name,int age){
this.name=name;
this.age=age;
}
public String toString(){
return "[name= "+name+" , age= "+age+" ]";
}
public void show(){
System.out.println("现在在调用show()方法,我是:"+toString());
}
}

通过反射访问成员变量

  • 获取成员变量的值用get(Objcet obj)、getInt(Object obj)、getLong(Object obj)、...以此类推
  • 设置成员变量的值用set(Objcet obj)、setInt(Objcet obj)、setLong(Objcet obj)、...以此类推
  • 如果是private修饰的变量,在访问之前用setAccessible(true)取消访问权限检查
  • 见示例:
package testpack;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field; public class Test1 {
public static void main(String[] args)throws Exception{
Class clazz=A.class;
Constructor c=clazz.getConstructor(String.class,int.class);
Object obj=c.newInstance("C++",28);
System.out.println(obj); //输出:[name= C++ , age= 28 ] Field nameField=clazz.getDeclaredField("name"); //获得name这个private成员变量
nameField.setAccessible(true); //取消对该变量的访问权限检查
System.out.println("private name="+nameField.get(obj)); //输出:private name=C++
Field ageField=clazz.getField("age"); //获得age这个public成员变量
System.out.println("public age= "+ageField.getInt(obj)); //输出:public age= 28 nameField.set(obj,"Java"); //将obj的private的name变量改为“Java”
ageField.setInt(obj, 100); //将obj的public的age变量改为100
System.out.println("修改了对象的private和public实例变量:"+obj); //输出:修改了对象的private和public实例变量:[name= Java , age= 100 ]
}
}
class A{
private String name;
public int age;
A(){
name="default";
age=0;
}
public A(String name,int age){
this.name=name;
this.age=age;
}
public String toString(){
return "[name= "+name+" , age= "+age+" ]";
} }
  • setAccessible()方法是Constructor、Field、Method的父类的AccessibleObject的方法,因此这三个类都可以用
  • 见示例:
package testpack;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method; public class Test1 {
public static void main(String[] args)throws Exception{
Class clazz=A.class;
Constructor c=clazz.getDeclaredConstructor(String.class,int.class);
c.setAccessible(true); //取消该构造器的访问权限检查
Object obj=c.newInstance("Java",18); //调用私有构造器
System.out.println(obj); Method m=clazz.getDeclaredMethod("show",null);
m.setAccessible(true); //取消show()方法的访问权限检查
m.invoke(obj, null); //调用私有方法
}
}
class A{
private String name;
public int age;
A(){
name="default";
age=0;
}
private A(String name,int age){ //private构造器
this.name=name;
this.age=age;
System.out.println("调用了private构造器");
}
public String toString(){
return "[name= "+name+" , age= "+age+" ]";
}
private void show(){ //private方法
System.out.println("在调用private方法:"+toString());
}
}

通过反射操作数组

  • java.lang.reflect.Array可用来操作数组
  • 创建一个数组:
    • static Object newInstance(Class<?>componentType,int...length):两个参数一个是类型,一个是长度
  • 访问某个数组元素:
    • static xxx getXxx(Object array,int index):返回array数组的第index个元素;引用类型则是:get(Object array,int index)
  • 设置某个数组元素的值
    • static void setXxx(Object array,int index,xxx value):设置数组array元素的第index个元素的值为value,引用类型:set(....)
  • 获取数组的长度
    • static int getLength(Object array):获得数组array的长度
  • 见示例:
package testpack;
import java.lang.reflect.Array;
public class Test1 {
public static void main(String[] args)throws Exception{
Object arr=Array.newInstance(String.class, 5); //调用构造方法
Array.set(arr, 0, "Java"); //将索引号为0的元素设置为“Java”
Array.set(arr, 1, "C++");
Array.set(arr, 2, "python");
System.out.println(Array.get(arr, 2)); //取得索引号为2的元素
System.out.println("array的长度:"+Array.getLength(arr)); //输出:array的长度:5
}
}

0034 Java学习笔记-反射-初步2-操作对象的更多相关文章

  1. 0033 Java学习笔记-反射-初步1

    先看看通过反射能干嘛 示例:修改对象的private实例变量 package testpack; import java.lang.reflect.Field; public class Test1 ...

  2. Java学习笔记--反射

    什么是Java反射 概念 java反射是指java能够在运行时确定类的类型信息,包括其方法.字段.构造函数等,并能够通过反射调用类或者类对象的方法.在Java中,java.lang.Class类与ja ...

  3. Java 学习笔记 ------第四章 认识对象

    本章学习目标: 区分基本类型与类类型 了解对象与参考的关系 从打包器认识对象 以对象观点看待数组 认识字符串的特性 一."=" 和 "==" 当=用于基本类型时 ...

  4. Java学习笔记--反射API

    反射API 1.反射API的介绍 通过反射API可以获取Java程序在运行时刻的内部结构.比如Java类中包含的构造方法.域和方法等元素,并可以与这些元素进行交换.     按照 一般地面向对象的设计 ...

  5. JAVA 学习笔记 - 反射机制

    1.   JAVA反射机制的概念 2. 怎样实例化一个 Class对象 Class.forName(包名.类名); 对象.getClass(); 类.class; ================== ...

  6. Java 学习笔记 反射与迭代器

    反射 使用反射获得类 Class cls = Class.forName("全类名") //包括包名 Class cls = xx.Class;//xx代表类名 使用反射获得构造方 ...

  7. Java学习笔记七(目录操作)

    1.介绍 上一篇博客介绍的是java中经常使用的操作文件的方式,本篇博客着重解说一下,在Java中是怎样来操作目录的.主要是利用的是Java.IO包以下的File类,本篇博客着重解说一下该类的构造函数 ...

  8. Java学习笔记——反射

    反射就是把Java类中的各种成分映射成相应的java类. Class类-->java程序中的各个java类属于同一事物,描述这类事物的Java类名就是Class. Class.forName的作 ...

  9. Java学习笔记-反射机制

    Java反射机制实在运行状态时,对于任意一个类,都能够知道这个类的属性和方法,对于任意一个对象,都能够调用他的任意一个属性和方法 获取Class对象的三种方式 Object类中的getClass()方 ...

随机推荐

  1. C# 开发windows服务的一些心得

    最近在做一个windows服务的项目,发现并解决了一些问题,拿出来和大家分享一下,以下windows服务简称“服务” 文章会在适合时间更新,因为朋友们在不断提出新的意见或思路,感谢-.- 1.服务如何 ...

  2. .NET Core采用的全新配置系统[1]: 读取配置数据

    提到“配置”二字,我想绝大部分.NET开发人员脑海中会立马浮现出两个特殊文件的身影,那就是我们再熟悉不过的app.config和web.config,多年以来我们已经习惯了将结构化的配置定义在这两个文 ...

  3. 理清JavaScript正则表达式--下篇

    紧接:"理清JavaScript正则表达式--上篇". 正则在String类中的应用 类String支持四种利用正则表达式的方法.分别是search.replace.match和s ...

  4. 开源Word读写组件DocX 的深入研究和问题总结

    一. 前言 前两天看到了asxinyu大神的[原创]开源Word读写组件DocX介绍与入门,正好我也有类似的自动生成word文档得需求,于是便仔细的研究了这个DocX. 我也把它融入到我的项目当中并进 ...

  5. Linux驱动开发—— of_property_read_u8

    在使用設備樹的時候, 有時會遇到下面的問題. 在設備樹中配置的屬性如下: fusb301,init-mode = <0x20>; 但是在驅動中讀出的卻是: rc = of_property ...

  6. IDEA+weblogic部署运行项目

    前段时间再服务器上为了部署一个系统,一直存在各种问题,不过过程中倒是把weblogic的部署掌握地特别熟练,下面就一些主要步骤做个记录:1.自己用的是IDEA,所以打开项目之后需要设置src/main ...

  7. GIS部分理论知识备忘随笔

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.高斯克吕格投影带换算 某坐标的经度为112度,其投影的6度带和3度带 ...

  8. 全自动迁移数据库的实现 (Fluent NHibernate, Entity Framework Core)

    在开发涉及到数据库的程序时,常会遇到一开始设计的结构不能满足需求需要再添加新字段或新表的情况,这时就需要进行数据库迁移. 实现数据库迁移有很多种办法,从手动管理各个版本的ddl脚本,到实现自己的mig ...

  9. CSS知识总结(六)

    CSS常用样式 4.段落样式 1)行高 控制段落内每行高度 line-height : normal | length 例子 源代码: /* CSS代码 */ .normal{ line-height ...

  10. ASP.NET MVC5学习笔记01

    由于之前在项目中也使用MVC进行开发,但是具体是那个版本就不是很清楚了,但是我觉得大体的思想是相同的,只是版本高的在版本低的基础上增加了一些更加方便操作的东西.下面是我学习ASP.NET MVC5高级 ...