一、实例化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)
一.软件测试 软件开发: 项目调研--需求分析--软件设计--程序编码--软件测试--运行维护 软件测试:利用测试工具按照测试方案和流程对产品进行功能和性能测试,使用人工或者自动手段来运行或测试某个系 ...
随机推荐
-
关于目录路径path
1.框架的目录结构 yii-1 .htaccess index.php protect -config -controllers -components 2.Linux 服务器 CentOs usr/ ...
-
Sqlserver_insert语法
1. INSERT INTO SELECT 通过 SQL,您可以从一个表复制信息到另一个表. INSERT INTO SELECT 语句从一个表复制数据,然后把数据插入到一个已存在的表中. 我们可 ...
-
iOS应用如何支持IPV6-b
果然是苹果打个哈欠,iOS行业内就得起一次风暴呀.自从5月初Apple明文规定所有开发者在6月1号以后提交新版本需要支持IPV6-Only的网络,大家便开始热火朝天的研究如何支持IPV6,以及应用中哪 ...
-
Phonegap 版本minSdkVersion为8的时候的自动更新与升级
清单文件中: <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="8"/> ...
-
使用JavaScript重定向URL参数
本人从网上查找(如有雷同,不胜荣幸.),并进行了修改,简单粗暴,实现使用JavaScript重置url参数 1.字符拼接形式 function setUri(para, val) { var strN ...
-
boost.property_tree读取中文乱码问题正确的解决方式
开发项目的时候在使用boost,在宽字符下遇到中文乱码问题 上网上看大家都是先转成utf8在进行解析的,例如: http://blog.csdn.net/hu_jiangan/article/deta ...
-
Keras和tf关系【转载】
转自:https://blog.csdn.net/capecape/article/details/78390246 TensorFlow和theano以及Keras都是深度学习框架,TensorFl ...
-
Linux网桥配置
CentOS:1.配置临时网桥,重启后风格配置丢失[root@CentOS ~]# yum -y install bridge-utils[root@CentOS ~]# brctl addbr br ...
-
怎么把焦点放在RichEdit的最后一行
急急急!!!!如何把焦点放在RichEdit的最后一行!! 请高手指点,在线等!!!!当添加到出现滚动条时焦点就不会往下了,怎么把焦点移到最后一行 RichEdit-> Lines-> A ...
-
更新Newtonsoft.Json后报异常,未能加载文件或程序集“Newtonsoft.Json
未能加载文件或程序集“Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed”或它的某一个 ...