![]()
反射创建对象,可以将 Java
类中的成员变量、成员方法等信息映射成一个个的 Java
对象,再使用这些对象进行操作
反射机制
1 2 3 4 5 6 7 8
| 在程序运行状态中
1. 构造任意一个类的对象 2. 得到任意一个对象所属的类的信息 3. 调用任何一个类的成员变量和方法 4. 获取任意一个对象的属性和方法
动态获取程序信息和动态调用对象的功能称为Java语言的反射机制
|
反射机制优点
# Class
类
JVM
编译 .java
文件生成对应的 .class
文件,然后将. class
文件加载到内存中执行,执行文件需要其他类的信息这个时候就需要反射;加载 .class
文件时,会产生一个 java.lang.Class
对象代表. class
字节码文件,从该 Class
对象可以获取类的信息
Class
是 JDK 自定义的类,提供了很多方法,通过调用 Class
类的成员方法可以获取 Class
对象中的信息,
常用方法
![]()
因为 ** Class
对象代表的是 .class
文件 (类), 所以所有的类实际上都是 Class
**** 类的实例,所有的对象都可以转变为 **** .class
** 类型表示
1 2 3 4 5 6 7 8 9
| 使用Class类必须完成实例化
实例化Class对象3种方式:
(1) 全限定类名获取: Class.forName("全限定类名") (2) 对象获取: 对象.getClass() (3) 类名获取: 类名.class
|
实例化类
1 2 3 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
| class b {
}
class a { public static void main(String[] args) { Class<?> c1 = null; Class<?> c2 = null; Class<?> c3 = null; try { c1 = Class.forName("b"); } catch (ClassNotFoundException e) { e.printStackTrace(); } c2 = new b().getClass(); c3 = b.class; System.out.println("类名称:" + c1.getName()); System.out.println("类名称:" + c2.getName()); System.out.println("类名称:" + c3.getName()); } }
-------------------------------------------------------------
输出:
类名称:b 类名称:b 类名称:b
|
关于 forName () 实例化异常
![]()
# 使用 Class
类
常见用法将 Class
类对象实例化为自定义类对象, 即可以通过一个给定的 字符串 (类的全限定类名) 实例化一个本类的对象,实例化为本类对象 通过无参构造完成,或者有参完成实例化本类对象
# 无参构造实例化对象
通过 Class
类实例化其他类的对象,使用 newInstance()
方法,但是必须保证被实例化的类中存在一个无参构造方法,否则无法实例化对象
1 2 3 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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| class Per{
private String name; private int age;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; } public String toString(){ return "姓名:" +this.name+"年龄:"+this.age; } }
class a {
public static void main(String[] args) { Class<?> c = null; try { c = Class.forName("Per"); }catch (ClassNotFoundException e){ e.printStackTrace(); } Per ka = null; try { ka = (Per) c.newInstance(); }catch (Exception e){ e.printStackTrace(); }
ka.setAge(30); ka.setName("180"); System.out.println(ka);
} }
----------------------------------------------------------------
输出:
姓名:180年龄:30
|
# 有参构造实例化对象
如果类中没有无参构造方法,则通过有参构造方法实例化对象,通过有参构造器实例对象,需要明确调用的构造方法,并且传递相应的参数
1 2 3 4 5 6 7
| 有参构造方法实例化对象步骤
(1) 通过Class类的getConstruclors()方法获取本类中的全部构造方法
(2) 向构造方法中传递一个对象数组,对象数组包含构造方法中所需的各个参数
(3) 通过Construclors类实例化对象
|
Construclors
类用于存储本类的构造方法,常用方法
![]()
1 2 3 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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| import java.lang.reflect.Constructor;
class per{ private String name; private int age;
public per(String name, int age) { this.name = name; this.age = age; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; } public String toString(){ System.out.println("姓名"+this.name+"年龄"+this.age); return "123"; } }
class a { public static void main(String[] args) { Class<?> c = null; try { c= Class.forName ("per"); }catch (ClassNotFoundException e){ e.printStackTrace(); }
per p = null; Constructor<?> saber[] = null; saber = c.getConstructors();
try { p = (per) saber[0].newInstance("小邓",100); }catch (Exception e){ e.printStackTrace(); } System.out.println(p);
} }
--------------------------------------------------------
输出:
姓名小邓年龄100 123
|
# 反射应用
通过反射可以得到一个类的完整结构,包括类的构造方法 类的属性 类的方法;需要使用 java.lang.reflect
包中的类
1 2 3 4 5
| Constructor : 表示类中的构造方法 Field: 表示类中的属性 Method: 表示类中的方法
这3个类都是AccessibleObject类的子类
|
# 获取实现全部接口 getInterfaces()
取得一个类所实现的全部接口,使用 Class
中的 getInterfaces()
方法 声明如下,它会返回一个 Class
类的对象数组,调用 Class
类中的 getName()
方法可以取得类的名称
1 2
| public Class[] getInterfaces ();
|
1 2 3 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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| interface China{ public static final String NATION = "CHINA"; public static final String AUTHOR = "张三"; } class per implements China{ private String name; private int age;
public per(String name, int age) { this.name = name; this.age = age; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public String toString(){ return "姓名"+this.name+"年龄"+this.age; } }
class a { public static void main(String[] args) { Class<?> c = null; try { c = Class.forName("per"); }catch (ClassNotFoundException e){ e.printStackTrace(); } Class<?> cons[] = c.getInterfaces(); for (int i = 0;i < cons.length;i++){ System.out.println("实现的接口名称"+cons[i].getName()); } } }
------------------------------------
输出:
实现的接口名称China
|
# 获取全部方法 getMethods()
取得类中全部方法,使用 Class
类中的 getMethods()
方法,该方法返回一个 Method
类的对象数组
它的常用方法是
![]()
1 2 3 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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| import java.lang.reflect.Method;
interface China{ public static final String NATION = "CHINA"; public static final String AUTHOR = "张三";
public void sayChina(); } class per implements China{ private String name; private int age;
public per(String name, int age) { this.name = name; this.age = age; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public String toString(){ return "姓名"+this.name+"年龄"+this.age; }
public void sayChina(){ System.out.println("你好世界"); } }
class a { public static void main(String[] args) { Class<?> c = null; try { c = Class.forName("per"); }catch (ClassNotFoundException e){ e.printStackTrace(); }
Method[] cons = c.getMethods(); for (int i = 0;i< cons.length;i++){ System.out.println("方法名称"+cons[i].getName()); } } }
----------------------------------------
输出:
不仅输出肉眼看到的方法还输出了Object类中继承的方法
方法名称toString 方法名称getName 方法名称setName 方法名称sayChina 方法名称setAge 方法名称getAge 方法名称wait 方法名称wait 方法名称wait 方法名称equals 方法名称hashCode 方法名称getClass 方法名称notify 方法名称notifyAll
|
# 获取全部属性 Field
类中的属性分为两部分
所以获取类的属性也有以下两种不同的方式,两种方式返回的都是 Field
数组,每个 Field
对象表示类中的一个属性,如果获取属性的详细信息就需要调用 Field
类的方法
1 2 3
| 1. 获取实现的接口或父类中的公共属性,public Field[] getFields throws SecurityException
2. 获取本类的全部属性: public Field[] getDeclaredFields throws SecurityException
|
![]()
1 2 3 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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| import java.lang.reflect.Field; import java.lang.reflect.Modifier;
class Per{
private String name;
private int age;
public Per(String name, int age) { this.name = name; this.age = age; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public String toString(){ return "姓名"+this.name+"年龄"+this.age; } }
class a { public static void main(String[] args) {
Class<?> c1 = null; try { c1 = Class.forName("Per"); }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.print(" ; ");
} } }
--------------------------------------------------------
输出:
本类属性private java.lang.String name ; 本类属性private int age ;
|