Java从零开始学四十一(反射简述二)
一、实例化Class类对象
- 第一种:通过forName()方法
- 第二种:类.class
- 第三种:对象.getClass()
二、Class类的常用方法
No.
|
方法
|
类型
|
描述
|
1
|
public static Class<?> forName(String className) throws ClassNotFoundException
|
普通
|
传入完整的“包.类”名称实例化Class对象
|
2
|
public Constructor[] getConstructors() throws SecurityException
|
普通
|
得到一个类中的全部构造方法
|
3
|
public Field[] getDeclaredFields() throws SecurityException
|
普通
|
得到一个类父类中的全部属性
|
4
|
public Field[] getFields() throws SecurityException
|
普通
|
取得本类的全部属性
|
5
|
public Method[] getMethods() throws SecurityException
|
普通
|
得到一个类中的全部方法
|
6
|
public Method getMethod(String name,Class... parameterTypes)
throws NoSuchMethodException,SecurityException
|
普通
|
返回一个Method对象,并设置一个方法中的所有参数类型
|
7
|
public Class[] getInterfaces()
|
普通
|
得到一个类中所实现的全部接口
|
8
|
public String getName()
|
普通
|
得到一个类完整的“包.类”名称
|
9
|
public Package getPackage()
|
普通
|
得到一个类的包
|
10
|
public Class getSuperclass()
|
普通
|
得到一个类的父类
|
11
|
public Object newInstance() throws InstantiationException,IllegalAccessException
|
普通
|
根据Class定义的类实例化对象
|
12
|
public Class<?> getComponentType()
|
普通
|
返回表示数组类型的Class
|
13
|
public boolean isArray()
|
普通
|
判断此Class是否是一个数组
|
三、获取类的信息
package com.pb.reflect;
/*
* 1.包
* 2.注解
* 3.构造方法
* 4.方法
* 5.内部类
*/
@Deprecated
public class ReflectDemo2 { //私有的构造方法
private ReflectDemo2(){};
//公有的带一个一个name属性的构造方法
public ReflectDemo2(String name){ };
//无参数的info方法
public void info(){};
//有参数的info方法
public void info(String str){};
//内部类
class inner{}; }
测试类
package demo; import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method; import com.pb.reflect.ReflectDemo2; public class Demo3 { public static void main(String[] args) throws SecurityException, NoSuchMethodException, ClassNotFoundException {
//获取ReflectDemo2的Class对象
Class<ReflectDemo2> cla=ReflectDemo2.class;
//获取ReflectDemo2中全部构造方法
Constructor[] constructors=cla.getDeclaredConstructors();
for (Constructor con : constructors) {
System.out.println(con);
}
//获取指定的公有构造方法
System.out.println("====获取指定的公有构造方法========");
Constructor [] pub=cla.getConstructors();
for (Constructor c : pub) {
System.out.println(c.toString());
}
//获取公有的方法
System.out.println("====获取公有的方法======");
Method [] methods=cla.getMethods();
for (Method meth : methods) {
System.out.println(meth.toString());
}
//获取指定方法
System.out.println("====获取指定的的方法======");
//获取info不带参数方法
Method method=cla.getMethod("info",null);
System.out.println(method.toString());
//获取info带一个String参数的方法
Method meth=cla.getMethod("info", String.class);
System.out.println(meth.toString());
System.out.println("=====获取注释=======");
Annotation [] annotations=cla.getAnnotations();
for (Annotation anno : annotations) {
System.out.println(anno.toString());
}
//获取得包信息
System.out.println("=====获取得包信息=======");
Package pack=cla.getPackage();
System.out.println(pack.toString());
//获取内部类
System.out.println("=====获取内部类=======");
Class [] clas=cla.getDeclaredClasses();
for (Class c : clas) {
System.out.println(c.toString());
}
System.out.println("=====获取父类=======");
Class class2=cla.getSuperclass();
System.out.println(class2.toString());
//获取内部类的对象
Class innercla=Class.forName("com.pb.reflect.ReflectDemo2$inner");
System.out.println("内部类对应的外部类:"+innercla.getDeclaringClass());
System.out.println("内部类的包:"+innercla.getPackage());
System.out.println("内部类的父类:"+innercla.getSuperclass());
} }
四、创建对象
直接使用newInstance方法创建对象
package demo; import java.util.Date; public class Demo4 { public static void main(String[] args) throws InstantiationException, IllegalAccessException {
//获取Date类的Class对象
Class cla=Date.class;
//使用newInstrance方法创建对象
Date date=(Date) cla.newInstance();
System.out.println(date.toString()); } }
指定的构造方法创建对象
package demo; import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Date; public class Demo4 { public static void main(String[] args) throws InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
//获取Date类的Class对象
Class cla=Date.class;
//获取指定参数的构造方法带一个长整型参数的构造方法
Constructor constructor=cla.getConstructor(long.class);
//使用newInstrance方法创建对象
Date date=(Date) constructor.newInstance(1999);
System.out.println(date.toString()); } }
五、调用方法
package com.pb.reflect; public class Person {
private String name;
private String gender;
private int age; public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
} public String getSay(){
return this.name+" \t"+this.gender+"\t"+this.age;
}
}
测试类
package demo; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import com.pb.reflect.Person; public class Demo6 { public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
//得到Person类的Class对象
Class cla=Person.class;
//声明一个Person对象
Person p=new Person();
//调用setName方法
Method method=cla.getMethod("setName", String.class);
//使用invoke赋值
method.invoke(p, "张三");
//调用setGender方法
Method setGender=cla.getMethod("setGender", String.class);
setGender.invoke(p, "女");
//调用setAge方法
Method setAge=cla.getMethod("setAge", int.class);
setAge.invoke(p, 23);
//调用get方法 get方法没有参数设置为null
Method getName=cla.getMethod("getName", null);
Object o=getName.invoke(p, null);
System.out.println(o.toString());
Method getGender=cla.getMethod("getGender", null);
Object o1=getGender.invoke(p, null);
System.out.println(o1.toString());
Method getAge=cla.getMethod("getAge", null);
Object o2=getAge.invoke(p, null);
System.out.println(o2.toString());
Method say=cla.getMethod("getSay", null);
Object o3=say.invoke(p, null);
System.out.println(o3.toString());
} }
结果:
张三
女
23
张三 女 23
六、调用属性
package com.pb.reflect; public class Person {
private String name;
private String gender;
private int age; public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
} public String getSay(){
return"姓名:"+this.name+" \t性别:"+this.gender+"\t年龄:"+this.age;
}
}
测试类
package demo1; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Calendar; import com.pb.reflect.Person; public class Test2 { public static void main(String[] args) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
//声明Person对象
Person p=new Person();
//通过反射重到Person的Class对象
Class cla=Person.class;
//因为Person类的属性都是私有的要用getDeclaredField
Field name=cla.getDeclaredField("name");
//临时取消权限检查
name.setAccessible(true);
name.set(p, "张三丰");
//获取年龄
Field gender=cla.getDeclaredField("gender");
//临时取消权限检查
gender.setAccessible(true);
//赋值
gender.set(p, "男");
//获取年龄
Field age=cla.getDeclaredField("age");
age.setAccessible(true);
age.setInt(p, 108);
//获取say方法
Method getSay=cla.getMethod("getSay", null);
Object o=getSay.invoke(p, null);
System.out.println(o.toString()); } }
实际在在使用已知类时没有必要使用反射,只有在程序需要动态创建某个类的对象的时候我们才会考虑使用反射
七、动态创建和访问数组
package demo1; import java.lang.reflect.Array; public class ArrayTest1 { /**
* 动态创建数组和访问数组
*/
public static void main(String[] args) {
//创建一个类型为String 的数组长度为10
Object arr=Array.newInstance(String.class, 10);
//依次为arr赋值
Array.set(arr, 0, "一");
Array.set(arr, 1, "二");
Array.set(arr, 2, "三");
Array.set(arr, 3, "四");
Array.set(arr, 4, "五");
Array.set(arr,5, "六");
Array.set(arr, 6, "七");
Array.set(arr, 7, "八");
Array.set(arr, 8, "九");
Array.set(arr, 9, "十"); //获取值
Object o8=Array.get(arr, 8);
System.out.println("数组 中下标为8的值为"+o8);
Object o2=Array.get(arr, 2);
System.out.println("数组 中下标为2的值为"+o2); } }
public static void main(String[] args) {
// 创建一个一维数组
Object arr1=Array.newInstance(int.class, 10);
//为下标为5,和8的赋值
Array.setInt(arr1, 5, 5);
Array.setInt(arr1, 8, 8);
//查看相应位置的内容
System.out.println(Array.get(arr1, 5));
System.out.println(Array.get(arr1, 8));
}
创建多维数组
package demo1; import java.lang.reflect.Array; public class ArrayTest2 { /**
* 使用Array类创建二维数组
*/
public static void main(String[] args) {
// 创建一个二维数组5,10
Object arr1=Array.newInstance(String.class, 5,10);
//为二维数组赋值
//首先获取一维的维灵敏
Object firstIndex=Array.get(arr1, 4);
//4,6赋值
Array.set(firstIndex, 6,"张三");
//为3,8赋值
Object new_firstindex=Array.get(arr1, 3);
Array.set(new_firstindex, 8, "李四");
//值输出
//将arr1数组强转为2维数组
String [][] str=(String [][])arr1;
System.out.println(str[4][6]);
System.out.println(str[3][8]); } }
Java从零开始学四十一(反射简述二)的更多相关文章
- Java从零开始学四十(反射简述一)
一.JAVA是动态语言吗? 一般而言,说到动态言,都是指在程序运行时允许改变程序结构或者变量类型,从这个观点看,JAVA和C++一样,都不是动态语言. 但JAVA它却有着一个非常突出的动态相关机制:反 ...
- Java从零开始学四十七(注解简述)
一.Java中注解Annotation 什么是注解:用来描述数据的数据(元数据). Java代码里的特殊标记.它为代码中添加用Java程序无法表达的额外信息提供一种形式化的方法,使用我们可以在未来的某 ...
- Java从零开始学四十二(DOM解析XML)
一.DOM解析XML xml文件 favorite.xml <?xml version="1.0" encoding="UTF-8" standalone ...
- Java从零开始学四十五(Socket编程基础)
一.网络编程中两个主要的问题 一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输. 在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可 ...
- Java从零开始学四十四(多线程)
一.进程与线程 1.1.进程 进程是应用程序的执行实例. 进程是程序的一次动态执行过程,它经历了从代码加载.执行到执行完毕的一个完整过程,这个过程也是进程本身从产生.发展到最终消亡的过程 特征: 动态 ...
- Java从零开始学三十一(DATE和Calendar类)
一.Date类 Date类是一个相对较为简单的操作类,在使用中直接使用java.util.Date类的构造方法并进行输出就可以得到一个完整的日期 二.Calendar类 Calendar类可以将取得的 ...
- Java从零开始学四十三(DOM4j解析XML)
一.创建XML // 建立XML public static void gernatorXML() { // 创建Document对象 Document doc = DocumentHelper.cr ...
- Java从零开始学四(数据类型)
一.Java数据类型划分 二.基本数据类型 No. 数据类型 大小/位 可表示的数据范围 1 long(长整数) 64 -9223372036854775808 ~ 92233720368547758 ...
- Java从零开始学四十六(Junit)
一.软件测试 软件开发: 项目调研--需求分析--软件设计--程序编码--软件测试--运行维护 软件测试:利用测试工具按照测试方案和流程对产品进行功能和性能测试,使用人工或者自动手段来运行或测试某个系 ...
随机推荐
- 解决MySQL建立连接问题,快速回收复用TCP的TIME_WAIT
最近同事遇到一个问题,使用python开发的工具在执行的时候无法和MySQL建立连接,其最直接的现象就是满篇的TIME_WAIT,最后通过调整tcp_timestamps参数问题得以解决,再次记录一下 ...
- Tasker to create toggle widget for ES ftp service -- Send Intent
To perform this mission, Tap the tab "tasks" of Tasker, create a task as below.Task: (ES F ...
- MyBatis入门实例-包括实体类与数据库字段对应&CLOB字段处理
1.我的开发环境是 jdk1.7+ecplise+oracle 11g 用到的jar包:mybatis-3.1.1.jar ojdbc6.jar 2.项目整体结构 3.首先配置conf.xml ...
- gcc 内联汇编
http://www.cnblogs.com/zhuyp1015/archive/2012/05/01/2478099.html
- rac 10g 10.2.0.1升级到10.2.0.5具体解释
RAC 10.2.0.1 升级到 10.2.0.5 一. 准备: Patch 包:p8202632_10205_LINUX.zip 节点数:3个节点 RAC1 RAC2 ...
- Android4.2.2启动动画前播放视频
首先声明測试平台为瑞芯微的rk3168,Android4.2.2,Android版本号非常重要,由于Android4.0和Android4.2.2的代码有些地方就有差别,并不通用! 首先接到任务不知怎 ...
- win8.1快速启动选项突然消失了怎么办?
win8开始提供的快速启动功能是一种混合式的休眠模式,Windows系统 在关机时将系统的信息保存到硬盘上的一个文件中来实现下一次的快速启动.当再次启动电脑时, Windows 使用该系统信息文件来恢 ...
- debian添加中文支持
转载:http://www.shunix.com/debian-chinese-support-472/ debian与ubuntu有很大的相似性,但是debian相对更原始,比如在语言支持这一块 ...
- [转载] MFC绘制动态曲线,用双缓冲绘图技术防闪烁
转载的原文地址 先上效果图 随着时间的推移,曲线向右平移,同时X轴的时间坐标跟着更新. 一.如何绘制动态曲线 所谓动画,都是一帧一帧的图像连续呈现在用户面前形成的.所以如果你掌握了如何绘制静态曲线,那 ...
- 【maven】排除maven中jar包依赖的解决过程 例子:spring cloud启动zipkin,报错maven依赖jar包冲突 Class path contains multiple SLF4J bindings.
一直对于maven中解决jar包依赖问题的解决方法纠结不清: 下面这个例子可以说明一个很简单的解决方法: 项目启动报错: Connected to the target VM, address: '1 ...