什么是反射?
反射就是把Java类中的各种成分映射成相应的Java类。例如:一个Java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的Java类来表示,就像汽车是一个类,汽车中的发动机,变速箱等等也是一个个类。表示Java类的Class类显然要提供一系列方法,来获得其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应的实例对象来表示,他们是Field、Method、Constructor、Package等等。
反射机制的优点与缺点
为什么要用反射机制?直接创建对象不就可以了吗,这就涉及到了动态与静态的概念,
静态编译:在编译时确定类型,绑定对象,即通过。
动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多态的应用,用以降低类之间的藕合性。
一句话,反射机制的优点就是可以实现动态创建对象和编译,体现出很大的灵活性,特别是在J2EE的开发。
它的缺点是对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它满足我们的要求。这类操作总是慢于只直接执行相同的操作。
获得class对象
1 package com.nanchen.reflect; 2 3 public class ClassDemo { 4 public static void main(String[] args) throws Exception { 5 6 //获取Class对象的三种方法 7 8 //1、类名.class--->String.class 9 Class<String> c = String .class; 10 11 //2、对象名.getClass--->new String().getClass() 12 Class d = new String().getClass(); 13 14 //3、Class.forName("类名")----->Class.forName("java.lang.String");//反射主要用这种 15 Class e = Class.forName("java.lang.String"); 16 } 17 }
反射----》获取Class中的构造方法Constuctor,方法Method,字段Filed
1 package com.nanchen.reflect; 2 3 public class Student { 4 public long stuNo; 5 public float score; 6 private String name; 7 private int age; 8 9 public Student(){} 10 public Student(String name,int age){ 11 this.name = name; 12 this.age = age; 13 } 14 15 public String getName() { 16 return name; 17 } 18 public void setName(String name) { 19 this.name = name; 20 } 21 public int getAge() { 22 return age; 23 } 24 public void setAge(int age) { 25 this.age = age; 26 } 27 private long getStuNo() { 28 return stuNo; 29 } 30 private void setStuNo(long stuNo) { 31 this.stuNo = stuNo; 32 } 33 private float getScore() { 34 return score; 35 } 36 private void setScore(float score) { 37 this.score = score; 38 } 39 @Override 40 public String toString() { 41 return "Student [stuNo=" + stuNo + ", score=" + score + ", name=" 42 + name + ", age=" + age + "]"; 43 } 44 45 }
获取构造方法
1 package com.nanchen.reflect; 2 3 import java.lang.reflect.Constructor; 4 5 public class Demo2 { 6 public static void main(String[] args) throws Exception { 7 Class<?> clazz = Class.forName("com.nanchen.reflect.Student"); 8 9 //获取public修饰的构造方法 10 Constructor [] constructors = clazz.getConstructors();//获取所有为public的构造方法 11 for (Constructor constructor : constructors) { 12 System.out.println(constructor); 13 } 14 15 System.out.println("------分割线---------"); 16 17 //获取指定的构造方法 18 Constructor cs1 = clazz.getConstructor(String.class,int.class); 19 System.out.println(cs1); 20 21 System.out.println("------分割线---------"); 22 23 //获取所有的构造方法,public,private,protected等修饰的 24 Constructor[] call = clazz.getDeclaredConstructors(); 25 for (Constructor constructor : call) { 26 System.out.println(constructor); 27 } 28 29 //用获取的构造方法创建对象,有参和无参 30 //有参的 31 Student stu = (Student) clazz.getConstructor(String.class,int.class).newInstance("zhangsan",88); 32 System.out.println(stu); 33 34 System.out.println("------分割线---------"); 35 36 //无参的 37 Student stu2 = (Student)clazz.getConstructor().newInstance(); 38 stu2.setAge(99); 39 stu2.setName("lisi"); 40 System.out.println(stu2); 41 42 } 43 }
执行结果:
public com.nanchen.reflect.Student() public com.nanchen.reflect.Student(java.lang.String,int) ------分割线--------- public com.nanchen.reflect.Student(java.lang.String,int) ------分割线--------- public com.nanchen.reflect.Student() public com.nanchen.reflect.Student(java.lang.String,int) Student [stuNo=0, score=0.0, name=zhangsan, age=88] ------分割线--------- Student [stuNo=0, score=0.0, name=lisi, age=99]
获取方法
1 package com.nanchen.reflect; 2 3 import java.lang.reflect.Method; 4 5 public class Demo3 { 6 public static void main(String[] args) throws Exception { 7 Class<?> clazz = Class.forName("com.nanchen.reflect.Student"); 8 9 //获取public修饰的方法 10 Method [] methods = clazz.getMethods(); 11 for (Method method : methods) { 12 System.out.println(method); 13 } 14 System.out.println("------分割线---------"); 15 16 //获取指定的方法 17 Student stu = new Student(); 18 Method setNameMethod = clazz.getMethod("setName",String.class); 19 setNameMethod.invoke(stu, "zhangsan");//第一个参数为此方法所在的对象,第二个参数为setName()方法需要传入的参数值 20 System.out.println(stu.getName()); 21 22 System.out.println("------分割线---------"); 23 24 //获取所有的方法,不能获取继承的方法 25 Method [] priMethods = clazz.getDeclaredMethods(); 26 for (Method method : priMethods) { 27 System.out.println(method); 28 } 29 30 System.out.println("------分割线---------"); 31 32 //获取特定private修饰的方法 33 Method setScoreMethod = clazz.getDeclaredMethod("setScore", float.class); 34 setScoreMethod.setAccessible(true);// 启用/禁用 访问控制权限 35 setScoreMethod.invoke(stu, (float)88.5); 36 37 Method getScoreMethod = clazz.getDeclaredMethod("getScore", null); 38 getScoreMethod.setAccessible(true);// 启用/禁用 访问控制权限 39 float score = (float) getScoreMethod.invoke(stu, null); 40 System.out.println(score); 41 } 42 43 }
执行结果:
public java.lang.String com.nanchen.reflect.Student.toString() public java.lang.String com.nanchen.reflect.Student.getName() public void com.nanchen.reflect.Student.setName(java.lang.String) public int com.nanchen.reflect.Student.getAge() public void com.nanchen.reflect.Student.setAge(int) public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException public final void java.lang.Object.wait() throws java.lang.InterruptedException public boolean java.lang.Object.equals(java.lang.Object) public native int java.lang.Object.hashCode() public final native java.lang.Class java.lang.Object.getClass() public final native void java.lang.Object.notify() public final native void java.lang.Object.notifyAll() ------分割线--------- zhangsan ------分割线--------- public java.lang.String com.nanchen.reflect.Student.toString() public java.lang.String com.nanchen.reflect.Student.getName() public void com.nanchen.reflect.Student.setName(java.lang.String) private void com.nanchen.reflect.Student.setScore(float) private float com.nanchen.reflect.Student.getScore() public int com.nanchen.reflect.Student.getAge() public void com.nanchen.reflect.Student.setAge(int) private long com.nanchen.reflect.Student.getStuNo() private void com.nanchen.reflect.Student.setStuNo(long) ------分割线--------- 88.5
获取字段
1 package com.nanchen.reflect; 2 3 import java.lang.reflect.Field; 4 import java.lang.reflect.Type; 5 6 public class Demo4 { 7 public static void main(String[] args) throws Exception { 8 Student stu = new Student(); 9 10 //获取public修饰的字段 11 Field[] fields = stu.getClass().getFields(); 12 for (Field field : fields) { 13 System.out.println(field); 14 15 if(field.getType() == float.class) 16 field.set(stu, (float)88.5);//为此字段赋值 17 18 if(field.getType() == long.class) 19 field.set(stu, 123456);//为此字段赋值 20 } 21 System.out.println(stu); 22 23 System.out.println("------分割线---------"); 24 25 //获取private修饰的字段,并为其赋值 26 Field nameField = stu.getClass().getDeclaredField("name"); 27 28 Type type = nameField.getType();//查看其类型 29 System.out.println(type); 30 31 nameField.setAccessible(true);// 启用/禁用 访问控制权限 32 nameField.set(stu, "zhangsan"); 33 String name = (String)nameField.get(stu);//获得name字段的值 34 System.out.println(name); 35 } 36 37 }
执行结果:
public long com.nanchen.reflect.Student.stuNo public float com.nanchen.reflect.Student.score Student [stuNo=123456, score=88.5, name=null, age=0] ------分割线--------- class java.lang.String zhangsan
浙公网安备 33010602011771号