框架:半成品软件,可以在框架的基础上进行软件开发,简化编码
反射:将类的各自组成部分封闭为其他对象,这就是反射机制。
2.1:反射好处:- 可以在程序运行过程中,操作这些对象
- 可以解耦,提高程序 的可扩展性
ClassLoader:是类加载器
**上述的图是Java代码在计算机的三个阶段:**也是 反射中获取Class对象的三种方式(每个阶段有一个方式)
1》Scource源代码阶段:
Java代码通过javac编译后变成java.class文件
java代码和java.class的这些文件都是在硬盘中
**2》Class类对象阶段:**通过类加载器将java.class封装成相应的对象,如:
成员变量 :Field[] fields (将成员变量封装成Field对象并且是一个数组)
构造方法:Constructor[] cons (将构造方法封装成Constructor对象并且是一个数组)
成员方法:Method[] methods (将成员方法封装成Method对象并且是一个数组)
3》目的是想加载进入内存被执行:
Runtime运行时阶段:
通过创建对象完成加载进入内存,被执行。
**2.2:获取Class对象的三种方式:上述的图是Java代码在计算机的三个阶段:也是 反射中获取Class对象的三种方式(每个阶段有一个方式)
-
Class.forName(“全包名”):将字节码文件加载进入内存,返回Class对象(注意的是:forName是静态方法可以通过类名.调用)
- 多于用配置文件,将类名定义在配置文件中,读取文件加载类
//Class.forName("全包名"):将字节码文件加载进入内存,返回Class对象;全包名=包名+类名 Class> aClass = Class.forName("com.haikang.person.Person"); System.out.println(aClass); -
类名.class:通过类名的属性class获取
- 多用于参数的传递
//2. 类名.class:通过类名的属性class获取 Class
personClass = Person.class; System.out.println(personClass); -
对象.getClass():getClass()方法在Object类中定义中
- 多用于对象的获取字节码的方式
// 3. 对象.getClass():getClass()方法在Object类中定义中 Person person = new Person(); System.out.println(person);
结论:
同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,无论通过哪一种方式获取的Class对象都是同一个,也就是hashCode值相同。
package com.haikang.person;
public class Person {
private String name;
private int id;
public Person() {
}
public Person(String name, int id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
package com.haikang.reflect;
import com.haikang.person.Person;
public class ReflectClass {
public static void main(String[] args) throws Exception {
//Class.forName("全包名"):将字节码文件加载进入内存,返回Class对象;全包名=包名+类名
Class> aClass = Class.forName("com.haikang.person.Person");
System.out.println(aClass);
//2. 类名.class:通过类名的属性class获取
Class personClass = Person.class;
System.out.println(personClass);
// 3. 对象.getClass():getClass()方法在Object类中定义中
Person person = new Person();
Class extends Person> aClass1 = person.getClass();
System.out.println(aClass1);
System.out.println(aClass==personClass);
System.out.println(aClass==aClass1);//等等号是比较地址
System.out.println(aClass.hashCode());
System.out.println(aClass1.hashCode());
System.out.println(personClass.hashCode());
//hashCode值相同说明是同一个对象
}
}
2.3:Class对象功能:
获取功能:
-
获取成员变量们:
Field[] getFields();
Field getField(String name)
Field[] getDeclaredFields();
Field getDeclaredField(String name)
package com.haikang.reflect;
import com.haikang.person.Person;
import java.lang.reflect.Field;
public class ReflectField {
public static void main(String[] args) throws Exception {
//获取PersonClass对象:
Class aClass = Person.class;
// Field[] getFields();只能获取publci修饰的成员变量
Field[] fields = aClass.getFields();
for (Field f:
fields) {
System.out.println(f);
}
Field string = aClass.getField("string");
Person person = new Person();
Object o = string.get(person);
System.out.println(o);//haikang
string.set(person,"eeje");
System.out.println(person.toString());
Field[] fields1 = aClass.getDeclaredFields();//说明getDeclaredFields()方法能获取所有成员方法
for (Field f1:
fields1) {
System.out.println(f1);
}
Field name = aClass.getDeclaredField("name");
//暴力反射:忽略访问权限修饰符的安全检查;要想获取反射get值,必须在get前进行暴力反射
name.setAccessible(true);
Object o1 = name.get(new Person());
System.out.println(o1);
Field id = aClass.getDeclaredField("id");
id.setAccessible(true);
Object o2 = id.get(person);
System.out.println(o2);
}
}
Field:成员变量的结果:
操作
-
设置值:
- void set(Object obj,Object value)
-
获取值:
- get(Object obj)
-
忽略访问权限修饰符的安全检查:
-
setAccessible(true);//暴力反射
-
2.获取构造方法们:
Constructor>[] getConstructors();
constructor getConstructor(类>…parameterTypes)
Constructor>[] getDeclaredConstructors();
Constructor getDeclaredConstructor(类>…parameterTypes)
Constructor:构造对象
创建对象:
- T newInstance(Object…initarges)
如果使用空参构造方法创建对象,操作可以简化:Class对象的newInstance()方法
下面该方法用于生成对象的:
-
-
T newInstance(Object... initargs) 使用此 Constructor对象表示的构造函数,使用指定的初始化参数来创建和初始化构造函数的声明类的新实例.
-
手写代码区:私有构造方法方法的目的只有一个,就是不让其他类创建该类对象
package com.haikang.reflect;
import com.haikang.person.Person;
import org.junit.Test;
import java.lang.reflect.Constructor;
public class ReflectConstructor {
@Test
//生成有参对象
public void test1() throws Exception{
//获取Person字节码对象
Class aClass = Person.class;
//获取构造器:
Constructor constructor = aClass.getConstructor(String.class,int.class,String.class);
//生成Person对象(是有参的)
Person person = constructor.newInstance("海康", 18, "eeje");
System.out.println(person);
}
//生成无参对象;无参生成对象有两种方式:一种是getConstructor()、一种是Class对象.newInstance()(在开发中建议使用用这种)
@Test
public void test2() throws Exception{
//获取Person字节码对象
Class personClass = Person.class;
//获取构造器
Constructor constructor = personClass.getConstructor();
//生成Person对象(无参)
Person person = constructor.newInstance();
System.out.println(person);
//生成无参的对象可以直接用Class中的newInstance()方法
Person person1 = personClass.newInstance();
System.out.println(person1);
}
@Test
public void testGetDeclaredConstructor() throws Exception {
Class personClass = Person.class;
Constructor constructor = personClass.getDeclaredConstructor(String.class, int.class, String.class);//该方法相对是构造方法被私有时使用
constructor.setAccessible(true);
Person person = constructor.newInstance("明瑞", 168, "eeje");
System.out.println(person);
}
}
3.获取成员方法们:
Method[] getMethods();
Method getMethod(String name,类>…parameterTypes)
Method[] getDeclaredMethods();
Method getDeclaredMethod(String name,类>…parameterTypers)
Method:方法对象
-
执行方法:第一参数是方法对象,第二是参数就是方法中的参数
Object invoke(Object obj,Object…args)
类>…parameterTypes:为参数类型如:String.class
-
获取方法名称:
String getName:获取方法名称
package com.haikang.reflect;
import com.haikang.person.Person;
import org.junit.Test;
import java.lang.reflect.Method;
public class ReflectMethod {
@Test
public void test1() throws Exception {
//获取Class对象
Class> aClass = Class.forName("com.haikang.person.Person");
//获取方法对象: Method getMethod(String name,类>...parameterTypes)
//方法无参形式
Method eat = aClass.getMethod("eat");
// public Object invoke(Object obj, Object... args)
eat.invoke(new Person());
}
@Test
public void test2() throws Exception {
//获取Class对象
Class aClass = Person.class;
// Method[] methods = aClass.getMethods();
// for (Method method:
// methods) {
// String name = aClass.getName();
// System.out.println(name);
// System.out.println(method);
// }
//获取方法对象: Method getMethod(String name,类>...parameterTypes)
//方法有参形式
Method add = aClass.getMethod("add", int.class, int.class);
add.invoke(new Person(),8,8);
}
@Test
public void test3() throws Exception {
//获取Class对象
Class aClass = Person.class;
Method inti = aClass.getMethod("inti");
inti.setAccessible(true);
inti.invoke(new Person());
}
}
4.获取类名:
String getName();



