0034 Java学习笔记-反射-初步2-操作对象
通过反射创建对象
- 通过反射创建对象有两种方式,一种通过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-操作对象的更多相关文章
- 0033 Java学习笔记-反射-初步1
先看看通过反射能干嘛 示例:修改对象的private实例变量 package testpack; import java.lang.reflect.Field; public class Test1 ...
- Java学习笔记--反射
什么是Java反射 概念 java反射是指java能够在运行时确定类的类型信息,包括其方法.字段.构造函数等,并能够通过反射调用类或者类对象的方法.在Java中,java.lang.Class类与ja ...
- Java 学习笔记 ------第四章 认识对象
本章学习目标: 区分基本类型与类类型 了解对象与参考的关系 从打包器认识对象 以对象观点看待数组 认识字符串的特性 一."=" 和 "==" 当=用于基本类型时 ...
- Java学习笔记--反射API
反射API 1.反射API的介绍 通过反射API可以获取Java程序在运行时刻的内部结构.比如Java类中包含的构造方法.域和方法等元素,并可以与这些元素进行交换. 按照 一般地面向对象的设计 ...
- JAVA 学习笔记 - 反射机制
1. JAVA反射机制的概念 2. 怎样实例化一个 Class对象 Class.forName(包名.类名); 对象.getClass(); 类.class; ================== ...
- Java 学习笔记 反射与迭代器
反射 使用反射获得类 Class cls = Class.forName("全类名") //包括包名 Class cls = xx.Class;//xx代表类名 使用反射获得构造方 ...
- Java学习笔记七(目录操作)
1.介绍 上一篇博客介绍的是java中经常使用的操作文件的方式,本篇博客着重解说一下,在Java中是怎样来操作目录的.主要是利用的是Java.IO包以下的File类,本篇博客着重解说一下该类的构造函数 ...
- Java学习笔记——反射
反射就是把Java类中的各种成分映射成相应的java类. Class类-->java程序中的各个java类属于同一事物,描述这类事物的Java类名就是Class. Class.forName的作 ...
- Java学习笔记-反射机制
Java反射机制实在运行状态时,对于任意一个类,都能够知道这个类的属性和方法,对于任意一个对象,都能够调用他的任意一个属性和方法 获取Class对象的三种方式 Object类中的getClass()方 ...
随机推荐
- egret调用页面js的方法。
参考文献: http://bbs.egret-labs.org/thread-267-3-1.html http://docs.egret-labs.org/post/manual/threelibs ...
- Python学习--03变量类型
变量赋值 Python中的变量不需要声明,变量的赋值操作既是变量声明和定义的过程. 每个变量在内存中创建,都包括变量的标识,名称和数据这些信息. 每个变量在使用前都必须赋值,变量赋值以后该变量才会被创 ...
- Atitit 外包管理规范attilax总结
Atitit 外包管理规范attilax总结 1. 常见的外包问题2 1.1. 使用了过时的语言与技术2 1.2. 不易扩展的架构,架构落后2 1.3. 使用了小众语言,框架类库,组件等技术,导致维护 ...
- Windows 10 部署Enterprise Solution 5.5
Windows 10正式版发布以后,新操作系统带来了许多的变化.现在新购买的电脑安装的系统应该是Windows 10.与当初用户不习惯Windows 7,购买新电脑后第一个想做的事情就是重装成XP,估 ...
- SQL Server 在缺少文件组的情况下如何还原数据库
SQL Server 在缺少文件组的情况下如何还原数据库 一.背景 我有一个A库,由于a,b两张表的数据量比较大,所以对表进行分区:在把A库迁移到一个新的集群上去,我只备份了A库的主分区过去进行还原为 ...
- 前端学HTTP之URL
× 目录 [1]URI [2]URL语法 [3]字符[4]编码方法 前面的话 一般地,URL和URI比较难以区分.接下来,本文以区分URL和URI为引子,详细介绍URL的用法 URI与URL的区别 U ...
- setTimeout那些事儿
一.setTimeout那些事儿之单线程 一直以来,大家都在说Javascript是单线程,浏览器无论在什么时候,都且只有一个线程在运行JavaScript程序. 但是,不知道大家有疑问没——就是我们 ...
- SQLCMD备忘录:执行文件夹所有Sql文件
在做性能测试的时候最希望的一件事情是数据自动导入. 一般做法就是写很多SQL文件,通过Bat自动执行所有Sql文件. Bat代码: @ECHO OFF SET SQLCMD="C:\Prog ...
- javaScript笔记
两边符号是tab键上面的那个键,不是单引号 即在sort内置的函数中先将各字符串转化为统一的大写或者小写,再进行比较即可. -------------------------------------- ...
- Google地图开发总结
我们经常使用地图查位置.看公交.看街景,同时地图还开放第三方的API给开发者.利用这些API进行地图的个性化的展示和控制,例如北京被水淹了,开发一个网页显示北京被淹的地图,地图上面标志被水淹的位置.严 ...