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)
一.软件测试 软件开发: 项目调研--需求分析--软件设计--程序编码--软件测试--运行维护 软件测试:利用测试工具按照测试方案和流程对产品进行功能和性能测试,使用人工或者自动手段来运行或测试某个系 ...
随机推荐
- interfacer和abstarct class的异同
- java值和地址值传递、字符串常量池的理解
#java值和地址值传递的理解: - 基本数据类型和基本数据类型的封装类都是:值传递 * 形式参数的改变不会影响实际参数的改变(相当于将值复制一份传递给形参,自身没做任何改变) - 引用数据 ...
- 说说最小生成树(Minimum Spanning Tree)
minimum spanning tree(MST) 最小生成树是连通无向带权图的一个子图,要求 能够连接图中的所有顶点.无环.路径的权重和为所有路径中最小的. graph-cut 对图的一个切割或者 ...
- The YubiKey -- COMPARISON OF VERSIONS
COMPARISON OF YUBIKEY VERSIONS BASICSTANDARD & NANO BASICEDGE & EDGE-N PREMIUMNEO & NE ...
- C#中汉字排序简单示例(拼音/笔划)
可以按照区域语言修改排序规则. class Program { static void Main(string[] args) { string[] arr = { "趙(ZHAO)&quo ...
- java线程的一些基础小知识
--------------------------------------------------------------------------------------------------线程 ...
- python笔记26-命令行传参sys.argv实际运用
前言 平常我们在用别人写好的python包的时候,在cmd输入xx -h就能查看到帮助信息,输入xx -p 8080就能把参数传入程序里,看起来非常酷. 本篇就来讲下如何在python代码里加入命令行 ...
- pytest文档17-fixture之autouse=True
前言 平常写自动化用例会写一些前置的fixture操作,用例需要用到就直接传该函数的参数名称就行了.当用例很多的时候,每次都传这个参数,会比较麻烦. fixture里面有个参数autouse,默认是F ...
- Configuring HDFS High Availability
Configuring HDFS High Availability 原文请訪问 http://blog.csdn.net/ashic/article/details/47024617,突袭新闻小灵儿 ...
- Visual Studio 2015官方社区版/专业版/专业版下载地址
Visual Studio 2015官方社区版/专业版/专业版下载地址 以下 Visual Studio 2015 社区版/专业版/专业版资源都是官方MSDN原版下载资源,统一为ISO格式镜像,使用解 ...