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)
一.软件测试 软件开发: 项目调研--需求分析--软件设计--程序编码--软件测试--运行维护 软件测试:利用测试工具按照测试方案和流程对产品进行功能和性能测试,使用人工或者自动手段来运行或测试某个系 ...
随机推荐
- hdoj 1753 大明A+B 高精度/java
大明A+B Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- UVALive 4425 Another Brick in the Wall 暴力
C - Another Brick in the Wall Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & ...
- 多线程_java多线程环境下栈信息分析思路
导读:Java多线程开发给程序带来好处的同时,由于多线程程序导致的问题也越来越多,而且对问题的查找和分析解决对于菜鸟程序原来是是件头疼的事.下面我就项目中使用多线程开发程序过程中遇到的问题做详细的分析 ...
- linux 定时任务 crontab 详细解释(转)
cron 是linux的内置服务,但它不自动起来,可以用以下的方法启动.关闭这个服务: 引用: /sbin/service crond start //启动服务 /sbin/service cr ...
- linux下mysql自动备份脚本
脚本放在 /home/user/mysql_backup.sh crontab # crontab -l # m h dom mon dow command 28 16 * * * /home/ ...
- 3D数学读书笔记——四元数
本系列文章由birdlove1987编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhurui_idea/article/details/25400659 什么是四元数 ...
- 在Hadoop中重写FileInputFormat类以处理二进制格式存储的整数
近期開始使用MapReduce,发现网上大部分样例都是对文本数据进行处理的,也就是说在读取输入数据时直接使用默认的TextInputFormat进行处理就可以.对于文本数据处理,这个类还是能满足一部分 ...
- 在EntityFramework6中管理DbContext的正确方式——2DbContext的默认行为(外文翻译)
(译者注:使用EF开发应用程序的一个难点就在于对其DbContext的生命周期管理,你的管理策略是否能很好的支持上层服务 使用独立事务,使用嵌套事务,并行执行,异步执行等需求? Mehdi El Gu ...
- java基础学习总结——Object类
一.Object类介绍
- Material Design(原质化设计)视觉设计语言规范 踏得网镜像
Android 5.0 Lollipop(棒棒糖,也就是之前的代称Android L)全面实践了谷歌最新研发的 Material Design 设计语言规范,只是该设计规范并不是仅针对移动平台. 我们 ...