反射
反射:Reflect,镜像。
反射是java的灵魂,如果指针是c的灵魂。
反射是一种语言的自省机制。
calss类型的实例无法人为创建,是由虚拟机创建并且每一个类型有唯一的class实例与之对应,所以不论的使用哪种方式获取同一个类的class类型,都是同一个 基本类型也有如 int.class dooule.class float.class char.class Integer.class byte.class long.class short.class boolean.class
java是一门静态编译型语言。但通过反射机制,使得java获得了一定的动态能力。动态能力指在程序运行期间,动态的改变或调整程序的逻辑或执行行为。
Class:描述类型的类型。
- 通过类名称.class来获取。2.通过对象.getClass()。3.Class.forName(“类全名”);
学生类:定义学生的属性和方法
package com.situ.chapter6;
public class Student {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private Student(String name) {
super();
this.name = name;
}
// public Student(String name) {
// super();
// this.name = name;
// }
}
package com.situ.chapter6;
public class Test1 {
public static class Student{
}
public static void main(String[] args) {
//第一种 类名.class
Class<?> clazz = String.class;//这里获取到的是lang包
System.out.println(clazz);
Class<?> clazz1 = Student.class;
System.out.println(clazz1);
//第二种 对象.getClass()
Student stu = new Student();
Class<?> clazz2 = stu.getClass();
System.out.println(clazz2);
//第三种 Class.forName("类全名") 如java.lang.String
try {
Class<?> clazz3 = Class.forName("com.situ.chapter6.Test1$Student");//注意这里是$符号,如果是(点)就会出现错误
System.out.println(clazz3);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
已经获取了类型的描述,那如何通过反射创建对象:
2. clazz.newInstance(); 可以创建对象的实例。适用于无参的构造方法,前提是构造方法对于调用者来说可见。
3.clazz.getDeclaredConstructor()获取构造方法,通过构造方法.newInstance()来创建对象。推荐。
Constructor:描述构造方法的类。可用于创建对象。
Field:对应于类的属性。
class实例.getDeclareField(“字段名”)
field实例.set(Object obj , Object value);
field实例.get(Object obj)
Field nameField = clazz.getDeclaredField(“name”);
System.out.println(nameField);
nameField.setAccessible(true);
nameField.set(stu2,“哈哈”);
获取本类中定义的属性:
getDeclaredField(name) 和getDeclareFields()
获取从祖先类中继承的属性(字段):
getField(name) 和getFields()
获取字段名
field.getName()
强制设置属性可见
field.setAccessable(boolean)
Method:对应类的方法
class实例.getDeclareMethod(“方法名”,参数列表)
Method method = clazz.getDeclaredMethod(“setName”, String.class);
method.invoke(stu2, “马六”);
获取当前类的公有方法:
getDeclaredMethod(String name ) 和getDeclaredMethods( )
获取从祖先类中定义的公有方法:
getMethod(String name) 和 getMethods()
通过反射的方式调用方法
method.invoke(对象,参数列表)
实例:
package com.situ.chapter6;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test2 {
public static void main(String[] args) {
//常用的创建对象方法
// Student st = new Student();
// st.setName("张三");
// System.out.println(st.getName());
//
//反射创建对象
Class<Student> clazz = Student.class;//获取学生类型的描述,即像镜像一样
try {
// //第一种方法 clazz.newInstance();,但是如果是对调用者来说是不可见的就不能用了,因为student类中有私有属性,所以不能使用,适用于无参构造
// Student stu1 = clazz.newInstance();
// stu1.setName("张三");
// System.out.println(stu1.getName());
//第二种方法clazz.getDeclaredConstructor()获取构造方法,通过构造方法.newInstance()来创建对象。推荐。
Constructor<Student> con = clazz.getDeclaredConstructor(String.class);
con.setAccessible(true);//访问权限设置为可见的
Student stu2 = con.newInstance("王五");
con.setAccessible(false);//关闭可见权限
System.out.println(stu2.getName());
//Field 描述字段(成员属性)的类
Field[] f =clazz.getDeclaredFields();
System.out.println(f.length);
Field nameField = clazz.getDeclaredField("name");
System.out.println(nameField);
nameField.setAccessible(true);
System.out.println(nameField.getName()+" "+nameField.get(stu2));
//method
Method method = clazz.getDeclaredMethod("setName", String.class);
method.invoke(stu2, "马六");
System.out.println(stu2.getName());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}
你知道哪些创建对象的方式?
- new 构造方法
- 反序列化。
- 反射。
- 克隆。
- 数组也是对象。new int[];
- 封箱拆箱:Integer a = 300; 等同于 Integer a = Integer.valueOf(300)
7.字符串:String a = “Hello world” + “张三” + “Hello world”