反射就是Java自我管理这些(类、对象)的机制。
1) 反射的作用(重点理解)
可以通过反射机制发现对象的类型,发现类型的方法/属性/构造器
可以创建对象并访问任意对象方法和属性等
2) Class加载
类加载到内存:Java将磁盘类文件加载到内存中,为一个对象(实例),这个对象是Class 的实例
3) Class实例代表Java中类型
获得基本类型实例
int.class
long.class
获得类类型(Class)实例
Class cls = String.class;
Class cls = Class.forName("java.lang.String");
Class cls = "abc".getClass();
以上方法获得的cls是同一个对象, 就是String 类内存加载的结果
通过反射获得对象的类/属性/方法/构造器
【案例】反射演示_“发现”对象的类/属性/方法/构造器
package bbs.itheima.com;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
public class ReflectDemo {
/**
* 反射演示
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
reflect("s");
//reflect(1);//java.lang.Integer
}
//反射方法
//用于发现 obj 的类型是什么?
// obj 有那些属性
// obj有那些方法,哪些构造器
public static void reflect(Object obj) {
// getClass()
//返回对象的类型,是OBject类的方法
Class cls = obj.getClass();
System.out.println("类:"+cls.getName());
//getDeclaredFields()
//返回在类上获得声明的所有属性(字段)
Field[] fields = cls.getDeclaredFields();
System.out.println("属性:");
for(Field field : fields){
System.out.println(
field.getType()+" :"+ //属性类型
field.getName());//属性名称
}
//getDeclaredMethods()
//返回类型上获得声明的所有方法
Method[] methods = cls.getDeclaredMethods();
System.out.println("方法");
for(Method method : methods){
System.out.println(method.getReturnType());
System.out.println(method.getName());
System.out.println(
Arrays.toString(method.getParameterTypes()));;
}
//getDeclaredConstructors()
//返回在类上获得声明的所有构造器
Constructor[] constructors =
cls.getDeclaredConstructors();
System.out.println("构造器");
for(Constructor c : constructors){
System.out.println(c.getName());
System.out.println(
Arrays.toString(c.getParameterTypes()));
}
}
}
通过反射创建对象实例
【案例】反射演示_根据类名创建对象实例
package bbs.itheima.com;
public class ReflectDemo1 {
public static void main(String[] args){
//执行crate()方法前提是参数类有午餐构造器
Object obj = create("bbs.itheima.com.Foo");
reflect(obj);
reflect(create("java.util.Date"));
}
//更具类名创建对象实例
public static Object create(String classname){
try{
/**
* 加载类
* 在classpth中查找对应得类
* 采用懒加载方式加载到内存
*
* */
Class cls = Class.forName(classname);
//创建类实例
Object obj = cls.newInstance();
return obj;
}catch(Exception e){
e.printStackTrace();
throw new RuntimeException("没搞定",e);
}
}
//反射方法
public static void reflect(Object obj){
}
class Foo{
int a = 3;
public double add(int b,Double d){
return a+b+d;
}
}
}
Class.forName() 静态方法,可以利用类名在CLASSPATH中查找对应的类,并且装载到内
存, 返回这个”class“
Class.forName()加载类的过程采用”懒惰方式”
”懒惰方式“,即检查发现如果已经加载了(内存中存在)就丌再加载,直接返回已经加载的 类,相当于“手工”去检查内存中是否已经加载了某个类
.newInstance()方法,会利用默认(无参数)构造器创建类实例(实例对象)
【案例】反射演示_访问某对象的某属性
package bbs.itheima.com;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
//反射演示
public class ReflectDemo2 {
public staticvoid main(String[] args) {
//执行crate()方法前提是参数类有午餐构造器
Objectobj = create("bbs.itheima.com.Foo");
System.out.println(
getFieldValue(obj,"a"));
}
根据类名创建对象实例
publicstatic Object create(String classname) {
try{
/**
* 加载类
* 在classpth中查找对应得类
* 采用懒加载方式加载到内存
*
* */
Classcls = Class.forName(classname);
//创建类实例
Objectobj = cls.newInstance();
returnobj;
}catch(Exceptione){
e.printStackTrace();
thrownew RuntimeException("没搞定",e);
}
}
publicstatic Object getFieldValue(Object obj,
Stringfieldname) {
try{
//反射出类型
Classcls = obj.getClass();
//反射出类型字段
Fieldfield = cls.getDeclaredField(fieldname);
//在对象上读取field属性的值
Objectval = field.get(obj);
returnval;
}catch(Exceptione){
e.printStackTrace();
thrownew RuntimeException("没搞定",e);
}
}
//反射方法
publicstatic void reflect(Object obj) {
}
class Foo{
int a = 3;
public double add(int b,Double d){
return a+b+d;
}
}
}