java基础-反射-day15
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,
都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
1. 案例引入
点外卖 有多种支付方式
微信支付 支付宝支付 。。。
接口
package com.msb.test01;
/**
* @Auther: jack.chen
* @Date: 2023/10/9 - 10 - 09 - 20:46
* @Description: com.msb.test01
* @version: 1.0
*/
public interface Pay {
void payOnline();
}
支付宝支付
package com.msb.test01;
/**
* @Auther: jack.chen
* @Date: 2023/10/9 - 10 - 09 - 20:48
* @Description: com.msb.test01
* @version: 1.0
*/
public class AliPay implements Pay {
@Override
public void payOnline() {
System.out.println("Ali pay");
}
}
微信支付
package com.msb.test01;
/**
* @Auther: jack.chen
* @Date: 2023/10/9 - 10 - 09 - 20:47
* @Description: com.msb.test01
* @version: 1.0
*/
public class WeChart implements Pay {
@Override
public void payOnline() {
System.out.println("We Chart pay");
}
}
银行卡支付
package com.msb.test01;
/**
* @Auther: jack.chen
* @Date: 2023/10/9 - 10 - 09 - 20:49
* @Description: com.msb.test01
* @version: 1.0
*/
public class BankPay implements Pay {
@Override
public void payOnline() {
System.out.println("bank card pay");
}
}
实现支付的方式1
package com.msb.test01;
/**
* @Auther: jack.chen
* @Date: 2023/10/9 - 10 - 09 - 20:50
* @Description: com.msb.test01
* @version: 1.0
*/
public class Test01 {
public static void main(String[] args) {
String str = "wechart";
if ("wechart".equals(str)){
pay(new WeChart());
}
}
public static void pay(WeChart wc){
wc.payOnline();
}
public static void pay(AliPay ap){
ap.payOnline();
}
public static void pay(BankPay bp){
bp.payOnline();
}
}
实现支付的方式2 多态
package com.msb.test01;
/**
* @Auther: jack.chen
* @Date: 2023/10/9 - 10 - 09 - 20:50
* @Description: com.msb.test01
* @version: 1.0
*/
public class Test02 {
public static void main(String[] args) {
String str = "wechart";
if ("wechart".equals(str)){
pay(new WeChart());
}
}
public static void pay(Pay p){
p.payOnline();
}
}
实现支付的方式3 反射
package com.msb.test01;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @Auther: jack.chen
* @Date: 2023/10/9 - 10 - 09 - 20:58
* @Description: com.msb.test01
* @version: 1.0
*/
public class Test03 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
String str = "com.msb.test01.AliPay";
Class clazz = Class.forName(str);
Object o = clazz.newInstance();
Method payOnline = clazz.getMethod("payOnline");
payOnline.invoke(o);
}
}
2. Class 的理解
Class 是对所有类的后抽象 所有的类 例如 Person Student 都只是Class 的一个实例而已
3. 反射的详细使用
获取 类的字节码
package com.msb.test01;
/**
* @Auther: jack.chen
* @Date: 2023/10/9 - 10 - 09 - 21:30
* @Description: com.msb.test01
* @version: 1.0
*/
public class Test04 {
public static void main(String[] args) throws ClassNotFoundException {
Person p = new Person();
Class c1 = p.getClass();
System.out.println(c1);
Class c2 = Person.class;
System.out.println(c2);
Class c3 = Class.forName("com.msb.test01.Person");
System.out.println(c3); //最常用
ClassLoader classLoader = Test04.class.getClassLoader();
Class c4 = classLoader.loadClass("com.msb.test01.Person");
System.out.println(c4);
//字节码只加载一次 所以 都是同一个 字节码 c1 == c2
}
}
4. Class 类都有哪些实例
Class类的具体的实例:
(1)类:外部类,内部类
(2)接口
(3)注解
(4)数组
(5)基本数据类型
(6)void
package com.msb.test01;
/**
* @Auther: jack.chen
* @Date: 2023/10/9 - 10 - 09 - 21:36
* @Description: com.msb.test01
* @version: 1.0
*/
public class Test05 {
public static void main(String[] args) {
Class c1 = Person.class;
Class c2 = Comparable.class;
Class c3 = Override.class;
int[] arr1 = {1,2,3};
Class c4 = arr1.getClass();
Class c6 = int.class;
Class c7 = void.class;
}
}
5. 详细使用
注解
package com.msb.test01;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
/**
* @Auther: jack.chen
* @Date: 2023/10/9 - 10 - 09 - 21:41
* @Description: com.msb.test01
* @version: 1.0
*/
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno {
String value();
}
接口
package com.msb.test01;
/**
* @Auther: jack.chen
* @Date: 2023/10/9 - 10 - 09 - 21:43
* @Description: com.msb.test01
* @version: 1.0
*/
public interface MyInterface {
void myMethod();
}
父类
package com.msb.test01;
import java.io.Serializable;
/**
* @Auther: jack.chen
* @Date: 2023/10/9 - 10 - 09 - 21:24
* @Description: com.msb.test01
* @version: 1.0
*/
public class Person implements Serializable {
private int age;
public String name;
public void eat(){
System.out.println("eating");
}
public void sleep(){
System.out.println("Sleeping");
}
}
子类
package com.msb.test01;
/**
* @Auther: jack.chen
* @Date: 2023/10/9 - 10 - 09 - 21:25
* @Description: com.msb.test01
* @version: 1.0
*/
@MyAnno(value="hello")
public class Student extends Person implements MyInterface {
private int sno;
double height;
protected double weight;
public double score;
@MyAnno(value="himethod")
public String ShowInfo(){
return "我是 一名三好学生";
}
private void work(){
System.out.println("Working");
}
public Student(){
System.out.println("空参 构造器");
}
public Student(int sno){
this.sno = sno;
}
public Student(int sno, double weight){
this.sno = sno;
this.weight = weight;
}
protected Student(int sno,double height,double weight){
this.sno = sno;
}
@Override
public void myMethod() {
System.out.println("Student override myMethod!!!");
}
@Override
public String toString() {
return "Student{" +
"sno=" + sno +
", height=" + height +
", weight=" + weight +
", score=" + score +
'}';
}
}
package com.msb.test01;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* @Auther: jack.chen
* @Date: 2023/10/9 - 10 - 09 - 21:49
* @Description: com.msb.test01
* @version: 1.0
*/
public class Test06 {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class cls = Student.class;
// 构造器的获取
Constructor[] constructors = cls.getConstructors();//只能获取当前运行时类的被public修饰的构造器
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
Constructor constructor1 = cls.getConstructor();
System.out.println(constructor1);//空参构造器
Constructor constructor = cls.getDeclaredConstructor(double.class, double.class);
System.out.println(constructor);//两个double参数的构造器
Constructor declaredConstructor = cls.getDeclaredConstructor(int.class);
System.out.println(declaredConstructor);//private修改的构造器
Object o1 = constructor1.newInstance();
System.out.println(o1);//创建对象
Object o2 = constructor.newInstance(180.0, 170.1);
System.out.println(o2);
}
}
6. 获取属性
package com.msb.test01;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
/**
* @Auther: jack.chen
* @Date: 2023/10/9 - 10 - 09 - 22:01
* @Description: com.msb.test01
* @version: 1.0
*/
public class Test07 {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, InstantiationException {
Class cls = Student.class;
Field[] fields = cls.getFields();//获取运行时类和父类中被public修饰的属性
for (Field field : fields) {
System.out.println(field);
}
Field[] declaredFields = cls.getDeclaredFields();
System.out.println(declaredFields);//获取运行时类中的所有属性
Field score = cls.getDeclaredField("score");
System.out.println(score);
Field sno = cls.getDeclaredField("sno");
System.out.println(sno);
//修饰符 modifiers
int modifiers = sno.getModifiers();
System.out.println(modifiers);
System.out.println(Modifier.toString(modifiers));
//获取filed的数据类型
Class type = sno.getType();
System.out.println(type.getName());
String name = sno.getName();
System.out.println(name);
Field score1 = cls.getField("score");
Object o = cls.newInstance();
score1.set(o, 98);
System.out.println(o);
}
}
7. 获取方法
package com.msb.test01;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
* @Auther: jack.chen
* @Date: 2023/10/9 - 10 - 09 - 22:10
* @Description: com.msb.test01
* @version: 1.0
*/
public class Test08 {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
Class cls = Student.class;
Method[] methods = cls.getMethods();//取运行时类的方法还有所有父类中的方法(被public修饰)
for (Method method : methods) {
System.out.println(method);
}
Method[] declaredMethods = cls.getDeclaredMethods();//获取运行时类中的所有方法
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
}
Method showInfo = cls.getMethod("ShowInfo");
System.out.println(showInfo);
Method work = cls.getDeclaredMethod("work", int.class);
System.out.println(work);
String name = work.getName();//方法的名字
System.out.println(name);
int modifiers = work.getModifiers();//方法的修饰符
System.out.println(Modifier.toString(modifiers));
Class<?> returnType = work.getReturnType();
System.out.println(returnType);
Class<?>[] parameterTypes = work.getParameterTypes();//方法的参数类型
for (Class<?> parameterType : parameterTypes) {
System.out.println(parameterType);
}
Object o = cls.newInstance();
Method myMethod = cls.getMethod("myMethod");
myMethod.invoke(o);
}
}
8 获取类的 接口 注解 所在的包
package com.msb.test01;
import java.lang.annotation.Annotation;
/**
* @Auther: jack.chen
* @Date: 2023/10/9 - 10 - 09 - 22:23
* @Description: com.msb.test01
* @version: 1.0
*/
public class Test09 {
public static void main(String[] args) {
Class cls = Student.class;
Class[] interfaces = cls.getInterfaces();
for (Class anInterface : interfaces) {
System.out.println(anInterface);
}
Class superclass = cls.getSuperclass();
System.out.println(superclass);
Class[] interfaces1 = superclass.getInterfaces();
for (Class c : interfaces1) {
System.out.println(c);
}
Package aPackage = cls.getPackage();
System.out.println(aPackage);
System.out.println(aPackage.getName());
Annotation[] annotations = cls.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
}
}
9. 思考
反射是否破坏了 封装
private proteted属性方法外部还是能访问到