java---反射机制

Java 应用程序的运行分为两种状态:
编译时:通过 javac 命令,生成一个或多个 .class 字节码文件。(每个类对应着一个 .class 字节码文件)
运行时:通过 java 命令,将生成的一个或多个 .class 字节码文件加载到内存中。(由 JVM 提供的类加载器完成)

类用于描述现实生活中的一类事物,类中有属性、有方法,但是因为类描述的是现实生活中的“一类”事物,因此
我们可以说类是抽象的。若需要具体到某一个事物,通过 new 关键字创建实例,操作属性,调用方法。
(因为我们在编译时就能够确定创建什么类的对象,操作什么属性和调用什么方法)

某种情况下,我们需要得知并使用一个在编译时完全未知的类,创建其对象,操作其属性,调用其方法。

//编译时
public <T> T get(Class<T> clazz){
return clazz.newInstance();
}

//运行时:调用方法时,方法运行
Person p = get(Person.class);
Customer cus = get(Customer.class);

//反射之前
Person p = new Person("张三", 18);
p.eat();
p.walk();

一、反射机制(Reflection):被视为动态语言的关键,在运行时得知并使用任意类
在运行时创建任意类的对象,在运行时获取并调用任意类对象的属性和方法。

Class 是开启反射的源头!

如何获取 Class 实例?
//1. 通过运行时类的 class 属性
Class clazz1 = Person.class;

//2. 通过运行时类对象的 getClass() 方法
Person p = new Person();
Class clazz2 = p.getClass();

//3. 通过 Class 静态方法 forName(String className)
String className = "com.atguigu.java.Person";
Class clazz3 = Class.forName(className);

//4. 通过类加载器(了解)
ClassLoader cl = this.getClass().getClassLoader();
Class clazz4 = cl.loadClass(className);

二、反射的功能
①在运行时判断任意对象的类
②在运行时创建任意类的对象
③在运行时判断任意对象的属性和方法
④在运行时调用任意对象的属性和方法
⑤生成动态代理
//在运行时获取运行时类带泛型父类的泛型类型
@Test
public void test7(){
Class clazz = Person.class;
//①获取带泛型父类的泛型类型
Type type = clazz.getGenericSuperclass();//com.atguigu.review.Creature<java.lang.String>

//②参数化类型
ParameterizedType pt = (ParameterizedType) type;
//③获取实际真实参数的数组
Type[] types = pt.getActualTypeArguments();
// Type t = types[0];
Class cl = (Class) types[0];
System.out.println(cl.getName());
}
//在运行时获取并调用运行时类的构造器
@Test
public void test5() throws Exception{
Class<Person> clazz = Person.class;
Constructor<Person> con = clazz.getDeclaredConstructor(String.class, int.class);
con.setAccessible(true);
Person p = con.newInstance("张", 18);
System.out.println(p);
}
//在运行时获取并调用运行时类对象的方法
@Test
public void test4() throws Exception{
Class clazz = Class.forName("com.atguigu.review.Person");
Person p = (Person) clazz.newInstance();
Method m1 = clazz.getMethod("eat");
m1.invoke(p);
System.out.println("----------------------------");
Method m2 = clazz.getMethod("setName", String.class, double.class, int.class);
Object obj = m2.invoke(p, "张", 99.99, 18);
System.out.println(obj);
System.out.println("----------------------------");
Method m3 = clazz.getDeclaredMethod("sleep");
m3.setAccessible(true); //忽略访问权限
Object obj2 = m3.invoke(p);
System.out.println("打印 sleep 方法的返回值:" + obj2);
}
//在运行时获取并操作运行时类对象的属性
@Test
public void test3() throws Exception{
Class clazz = Class.forName("com.atguigu.review.Person");
Person p = (Person) clazz.newInstance();
Field age = clazz.getField("age");
//设置属性值
age.set(p, 18);
//获取属性值
Object obj = age.get(p);
System.out.println(obj);
System.out.println("----------------------------");
Field name = clazz.getDeclaredField("name");
name.setAccessible(true); //忽略访问权限
name.set(p, "张");
System.out.println(name.get(p));
}
//在运行时创建运行时类的实例 : newInstance() 默认调用无参构造器
@Test
public void test2() throws Exception{
Class clazz = Person.class;
Person p = (Person) clazz.newInstance();
System.out.println(p);
}
//通过类加载器加载属性文件
@Test
public void test1() throws IOException{
Properties props = new Properties();
ClassLoader cl = this.getClass().getClassLoader();
InputStream in = cl.getResourceAsStream("com/atguigu/review/jdbc.properties");
props.load(in);
String userName = props.getProperty("username");
String password = props.getProperty("password");
System.out.println(userName);
System.out.println(password);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值