框架:半成品软件,可以在框架的基础上进行软件开发,简化编码
反射:将类的各个组成部分封装为其他对象,这就是反射机制
好处:
* 可以在程序运行过程中,操作这些对象。
* 可以解耦,提高程序的可扩展性。
一、基本概念
在反射机制中,还可以通过反射得到一个类的完整结构,这就需要使用 java.lang.reflect
包中的以下几个类:
Constructor:表示类中的构造方法
Field:表示类中的属性
Method:表示类中的方法
这三个类都是 AccessibleObject 类的子类:
interface China{
public static final String NATIONAL = "China";
public static final String AUTHOR = "Java";
public void sayChina();//定义无参的抽象方法
public String sayHello(String name,int age);//定义有参的抽象方法
}
class Person implements China{
private String name;
private int age;
public Person(){
}
public Person(String name){//声明有一个参数的构造方法
this.name = name;
}
public Person(String name,int age){
this(name);
this.setAge(age);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public void sayChina() {
System.out.println("作者:" + AUTHOR + ",国籍:" + NATIONAL);
}
@Override
public String sayHello(String name, int age) {
return name + "你好!我今年" + age + "岁了!";
}
}
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
二、取得所实现的全部接口
要取得一个类所实现的全部接口,必须使用 Class 类中的 getInterfaces() 方法,该方法定义:
public Class[] getInterfaces()
- 1
getInterfaces() 方法返回一个 Class 类的对象数组,之后直接利用 Class 类中的 getName() 方法输出即可。
public class Root{
public static void main(String[] args) {
Class<?> c1 = null;//声明 Class对象
try{
c1 = Class.forName("Person");
}catch (ClassNotFoundException e){
e.printStackTrace();
}
Class<?> c[] = c1.getInterfaces();//取得实现的全部接口
for (int i=0;i<c.length;i++){
System.out.println("实现的接口名称:" + c[i].getName());//输出接口名称
}
}
}
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
因为接口是类的特殊形式,而且一个类可以实现多个接口,所以此时以 Class 数组的形式将全部的接口对象返回,并利用循环的方式将内容依次输出
三、取得父类
一个类可以实现多个接口,但是只能继承一个父类,所以要想取得一个类的父类,可以直接使用 Class 类中的 getSuperclass() 方法,该方法定义:
public Class<? super T> getSuperclass()
- 1
getSuperclass() 方法返回的是 Class 实例,和之前得到的接口一样,可以通过 getName() 方法取得名称。
public class Test{
public static void main(String[] args) {
Class<?> c1 = null;
try {
c1 = Class.forName("Person");
}catch (ClassNotFoundException e){
e.printStackTrace();
}
Class<?> c2 = c1.getSuperclass();//取得父类信息
System.out.println("父类名称:" + c2.getName());
}
}
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
Person 类在编写时没有明确地继承一个父类,所以默认继承 Object 类
四、取得全部构造方法
要取得一个类中的全部构造方法,必须使用 Class 类中的 getConstructors() 方法。
- 取得 Person 类的全部构造方法
import java.lang.reflect.Constructor;
public class Test{
public static void main(String[] args) {
Class<?> c1 = null;
try {
c1 = Class.forName("Person");
}catch (ClassNotFoundException e){
e.printStackTrace();
}
Constructor<?> con[] = c1.getConstructors();//得到全部构造方法
for (int i=0;i<con.length;i++){
System.out.println("构造方法:" + con[i]);
}
}
}
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 取得一个类的全部构造方法
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
public class Test{
public static void main(String[] args) {
Class<?> c1 = null;
try {
c1 = Class.forName("Person");
}catch (ClassNotFoundException e){
e.printStackTrace();
}
Constructor<?> con[] = c1.getConstructors();//得到全部构造方法
for (int i=0;i<con.length;i++){
Class<?> p[] = con[i].getParameterTypes();//列出构造中的参数类型
System.out.print("构造方法:");
int mo = con[i].getModifiers();//取出权限
System.out.print(Modifier.toString(mo) + " ");//还原权限
System.out.print(con[i].getName());//输出构造方法名称
System.out.print("(");
for (int j=0;j<p.length;j++){
System.out.print(p[j].getName() + " arg" + i);
if (j<p.length-1){//打印参数类型,判断是否要输出“,”
System.out.print(",");
}
}
System.out.println("){}");
}
}
}
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
五、取得全部方法
要取得一个类中的全部方法,可以使用 Class 类中的 getMethods() 方法,该方法返回一个 Method 类的对象数组。该方法的常用方法:
取得一个类的全部方法定义:
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class Test{
public static void main(String[] args) {
Class<?> c1 = null;
try {
c1 = Class.forName("Person");
}catch (ClassNotFoundException e){
e.printStackTrace();
}
Method m[] = c1.getMethods();//取得全部的方法
for (int i=0;i<m.length;i++){
Class<?> r = m[i].getReturnType();//取出方法的返回值类型
Class<?> p[] = m[i].getParameterTypes();//得到全部的参数类型
int xx = m[i].getModifiers();//得到方法的修饰符
System.out.print(Modifier.toString(xx) + " ");//还原修饰符
System.out.print(r.getName() + " ");//得到方法名称
System.out.print(m[i].getName());//取得方法名称
System.out.print("(");
for (int x=0;x<p.length;x++){
System.out.print(p[x].getName() + " " + "arg" + x);//输出参数
if (x<p.length-1){
System.out.print(",");//判断是否输出","
}
}
Class<?> ex[] = m[i].getExceptionTypes();//得到全部的异常抛出
if (ex.length>0){
System.out.print(") throws ");//输出“) throws”
}else {
System.out.print(")");
}
for (int j=0;j<ex.length;j++){
System.out.print(ex[j].getName());//输出异常信息
if (j<ex.length-1){
System.out.print(",");
}
}
System.out.println();
}
}
}
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
开发工具就是利用了反射的原理
六、取得全部属性
在反射操作中也同样可以取得一个类中的全部属性,有两种不同的操作:
得到实现的接口或父类中的公共属性:public Field[] getFields() throws SecurityException
得到本类中的全部属性:public Field[] getDeclareDeclaredFields() throws SecurityException
- 1
- 2
上述方法返回的都是 Field 的数组,每一个 Field 对象表示类中的一个属性,而要想取得属性的进一步信息,需要使用:
取得 Person 类中的属性
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class Test{
public static void main(String[] args) {
Class<?> c1 = null;
try {
c1 = Class.forName("Person");
}catch (ClassNotFoundException e){
e.printStackTrace();
}
{//普通代码块
Field f[] = c1.getDeclaredFields();//取得本类属性
for (int i=0;i<f.length;i++){
Class<?> r = f[i].getType();//取得属性的类型
int mo = f[i].getModifiers();//得到修饰符数字
String priv = Modifier.toString(mo);//取得属性的修饰符
System.out.print("本类属性:");
System.out.print(priv + " ");//输出修饰符
System.out.print(r.getName() + " ");//输出属性类型
System.out.print(f[i].getName());//输出属性名称
System.out.println(";");//换行
}
}
System.out.println("===========================");
{
Field f[] = c1.getFields();//取得父类公共属性
for (int i=0;i<f.length;i++){
Class<?> r = f[i].getType();//取得属性的类型
int mo = f[i].getModifiers();//取得修饰符数字
String priv = Modifier.toString(mo);//取得属性修饰符
System.out.print("公共属性:");
System.out.print(priv + " ");//输出修饰符
System.out.print(r.getName() + " ");//输出参数类型
System.out.print(f[i].getName());//输出属性名称
System.out.println(";");
}
}
}
}
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40