有对象必须先有类,static修饰类的属性与方法 在java中存储了类的内容,这个内容也应该是一个对象 java中用到的每一个类都会有一个内存,这每一块内容都是一个对象 这些对象用于记录这些类中声明了哪些方法和构造方法 java将这些类抽象为一个Class类
类的类对象中存储了类定义的内容 ---属性 方法 构造方法 一开始可以不知道是哪一个类(类对象),可以通过传入参数获取---框架思想
反射机制相关的重要的类有哪些?
答:java.lang.Class:代表整个字节码,代表一个类型,代表整个类。
java.lang.reflect.Method:代表字节码中的方法字节码,代表类中的方法。
java.lang.reflect.Constructor:代表字节码中的构造方法字节码,代表类中的构造方法。
java.lang.reflect.Field:代表字节码中的属性字节码,代表类中的成员变量(静态变量+实例变量)。
反射:在程序运行期间可以动态获取类中定义的属性与方法以及构造方法的机制(思想)的实现 *反射核心机制:Class类, 每一个程序中使用的类都有唯一一个对应的Class对象 *反射的API(API:可以调用的属性与方法,构造方法):Field Method Constructor *反射会破化类的封装性 (要通过特殊的场景进行分析,封装性与反射没有绝对的好与坏) * ---> setAccessible超出访问权限修饰符相应的访问范围时,就需要首先获取访问权限(设置为true)
1.通过类名获取类对象
2.通过对象获取类对象
3.通过Class方法的forName方法获取类对象
// 1.通过类名获取类对象
Class clazz=EasyClassA.class;
//2.通过对象获取类对象
clazz=new EasyClassA().getClass();
//3.通过Class方法的forName方法获取类对象
clazz=Class.forName("com.easy7_25.EasyColor_Enum");
System.out.println(clazz);
第四种:使用系统的类加载器(了解)
Class c = ClassLoader.getSystemClassLoader().loadClass("java.util.Date");
getField(String name):
Field
对象,表示该类或其父类的指定公共字段。NoSuchFieldException
。getFields():
Field
数组,包含该类及其父类的所有公共字段。getDeclaredField(String name):
Field
对象,表示该类的指定字段。NoSuchFieldException
。总结:
getField
和getFields
只能获取公共字段,包括继承的公共字段。getDeclaredField
可以获取所有字段,不考虑访问权限,但不包括继承的字段。 //获取类对象
Class clazz=Easy.class;
//获取类的属性
//java中用来记录 类的属性的类叫做Field
//fName变量指向的对象就是Easy类中的name属性
Field fName=clazz.getField("name");
//可以获取某一个Easy类的对象的name属性的值
//--面向对象思想获取name
Easy easy=new Easy();
easy.name="zhangsan";
System.out.println(easy.name+"---------");//zhangsan---------
//--反射思想获取name
Object objectName = fName.get(easy);
System.out.println(objectName);//zhangsan
fName.set(easy,"lisi");
System.out.println(easy.name);//lisi
//getField getFields只能获取类中的public声明的属性---getDeclaredField(任何都可以)
Field fCode= clazz.getDeclaredField("code");
fCode.set(easy,"10001");
Object objCode = fCode.get(easy);
System.out.println(objCode);//10001
Field fsex = clazz.getDeclaredField("sex");
Field faddress = clazz.getDeclaredField("address");
fsex.set(easy,"男");
//反射访问私有属性,必须先获取访问权限(设置为true)--setAccessible(true)
//超出访问权限修饰符相应的访问范围时,就需要首先获取访问权限(设置为true)
faddress.setAccessible(true);
faddress.set(easy,"青岛");
System.out.println(faddress.get(easy));//青岛
getDeclaredMethods()
反射获取方法 Method---一般用于初始化时 getMethod获取public方法 getDeclaredMethod--all 调用方法 --面向对象思想:对象.方法名() // 反射:method.invoke(对象) ---让某一个对象执行此方法
获取方法:
getMethod(String name, Class... parameterTypes)
:
Method
对象,表示该类或其父类的指定公共方法。NoSuchMethodException
。getMethods()
:
Method
数组,包含该类及其父类的所有公共方法。getDeclaredMethod(String name, Class... parameterTypes)
:
Method
对象,表示该类的指定方法。NoSuchMethodException
。getDeclaredMethods()
:
Method
数组,包含该类的所有声明方法。方法信息:
获取方法的名称 getName()
获取方法的返回类型 getReturnType() -->
返回一个Class
对象,表示方法的返回类型。
方法调用:invoke(对象,……对象)
反射:method对象.invoke(对象,……对象) ---让某一对象执行此方法
: // 反射包 java.lang.reflect
//获取类对象
Class c=Easy.class;
//反射获取方法 Method---一般用于初始化时
Easy easy=c.newInstance();
//getMethod获取public方法 getDeclaredMethod--私有
Method ma=c.getMethod("methodA");
//调用方法 --面向对象思想:对象.方法名()
// 反射:method.invoke(对象) ---让某一个对象执行此方法
ma.invoke(easy);
Method mb=c.getMethod("methodB",int.class,int.class);
mb.invoke(easy,23,45);
public class Easy {
public String name;
protected String code;
String sex;
private String address;
public static final transient String test=null;
static int maxage;
public Easy(){}
public Easy(String name){
this.name=name;
}
public void methodA(){
System.out.println("methodA");
}
public void methodB(int a,int b){
System.out.println("methodB");
System.out.println("两个参数分别是"+a+b);
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("设置setName-------");
this.name = name;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
System.out.println("-----setAddress");
this.address = address;
}
public static int getMaxage() {
return maxage;
}
public static void setMaxage(int maxage) {
Easy.maxage = maxage;
}
}
getConstructor() 反射获取构造方法--没有返回值,没有返回值类型,方法名与类名一样
getConstructor(Class... parameterTypes)
:
Constructor
对象,表示该类的指定公共构造函数。NoSuchMethodException
。getConstructors()
:
Constructor
数组,包含该类的所有公共构造函数。getDeclaredConstructor(Class... parameterTypes)
:
Constructor
对象,表示该类的指定构造函数。NoSuchMethodException
。getDeclaredConstructors()
:
Constructor
数组,包含该类的所有声明构造函数//getConstructor() 反射获取构造方法--没有返回值,没有返回值类型,方法名与类名一样
Class c=Easy.class;
//!!!!!!!!!!!!
c.newInstance();//调用无参构造方法创建实例
//获取无参构造方法
Constructor con = c.getConstructor();
//!!!!!!!!!!!!!!!!
con.newInstance();//调用无参构造方法创建实例
con=c.getConstructor(String.class);
//!!!!!!!!!!!
con.newInstance("zhangsan");调用有参构造方法创建实例
调用构造函数来创建一个新的对象实例:newInstance(Object... initargs)
new
:只能访问公共构造函数。对象.newInstance
:可以访问所有构造函数(包括私有构造函数),但需要设置可访问性(setAccessible(true)
)getModifiers()
getModifiers()
方法用于获取类、方法、字段或构造函数的修饰符。修饰符是一些关键字,如public
、private
、static
等,它们定义了这些元素的访问权限和行为。getModifiers()
方法返回一个整数,这个整数代表了修饰符的位掩码(bitmask)。每个修饰符对应一个特定的位,通过按位与(&
)操作可以判断某个修饰符是否存在。例如,假设modifiers
的值是9(即public
和static
的组合),那么:
modifiers & 1
(检查public
)的结果是1,表示方法具有public
修饰符。
modifiers & 8
(检查static
)的结果是8,表示方法具有static
修饰符。
公共类, 无参构造函数,属性私有化,Getter和Setter方法,序列化
公共类:JavaBean类必须是公共的(public
),以便其他类可以访问它。
无参构造函数:必须有一个无参的公共构造函数。这是为了确保可以通过反射机制创建实例。
属性私有化:通过公共的getter和setter方法来访问和修改这些属性。
Getter和Setter方法:getter方法用于获取属性的值,setter方法用于设置属性的值
序列化:通常实现java.io.Serializable
接口,以便可以序列化和反序列化。
PropertyDescriptor
:描述JavaBean的属性。MethodDescriptor
:描述JavaBean的方法。BeanInfo
:提供对JavaBean的详细信息的访问(3)获取JavaBean的详细信息:getBeanInfo
Introspector.getBeanInfo(类对象)
java.beans.Introspector
类,通过调用该方法可以获取一个BeanInfo
对象,该对象包含了JavaBean的属性、方法、事件等详细信息。 /*内省:也是通过反射实现 但不会破化封装性*/
//获取BeanInfo
BeanInfo bi = Introspector.getBeanInfo(c);
//获取属性写与读的方法 setter getter
//getPropertyDescriptors 获取属性的
PropertyDescriptor[] pds = bi.getPropertyDescriptors();
System.out.println(Arrays.toString(pds));
//获取属性的名字
String name = pds[0].getName();
System.out.println("属性名字"+name);
//获取读的方法---对应属性的getter方法
Method read = pds[0].getReadMethod();
//获取写的方法---对应属性的setter方法
Method write = pds[0].getWriteMethod();
//面向对象 -- obj.setName("zhangsan");
//反射 -- write.invoke(obj)
Easy easy = c.newInstance();
write.invoke(easy,"zhangsan");