package com.day14.json
import org.junit.Test
import java.io.IOException
import java.io.InputStream
import java.lang.annotation.Annotation
import java.lang.reflect.*
import java.util.Properties
import java.util.Random
/**
* Author: Json
* Date: 2021/10/6
**/
public class JsonTest {
public static void main(String[] args) {
System.out.println("加油把")
//java 反射机制
}
@Test
public void test1(){
//反射之前 的操作
//1.创建对象
Person person=new Person("JSON",12)
//2. 调用内部属性 方法
person.show()
//在person类的外部不能调用私有的方法或属性
}
@Test
public void test2() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
//反射之后
Class c= Person.class
// 1.通过反射 创建Person类的对象
Constructor constructor=c.getConstructor(String.class,int.class)
Object object= constructor.newInstance("Json",123)
System.out.println(object.toString())
//强转
Person person =(Person) object
System.out.println(person.getName())
//2.通过反射 调用对象的指定的方法和属性
//调用更改类里的属性
Field age=c.getDeclaredField("age")
age.set(person,12)
System.out.println(person.toString())
//调用类中方法
Method show=c.getDeclaredMethod("show")
show.invoke(person)
//通过反射是可以调用Person类中的私有结构的
//如果 私有方法 私有构造器 私有属性
//调用私有的构造器
Constructor constructor1= c.getDeclaredConstructor(String.class)
//激活私有方法权限调用 保持当前属性是可访问的
constructor1.setAccessible(true)
Person person1=(Person) constructor1.newInstance("whL")
System.out.println(person1.getName())
//调用修改私有属性
Field name=c.getDeclaredField("name")
name.setAccessible(true)
name.set(person1,"hahah")
System.out.println(person1)
//调用私有方法
Method eat=c.getDeclaredMethod("eat", String.class)
eat.setAccessible(true)
String naa= (String) eat.invoke(person1,"21312321")
System.out.println(naa)
}
// 通过直接new的方式或反射的方式都可以调用公共的结构 开发中用哪个?
//建议 直接new的方式
//什么时候会使用反射的方式? 反射的特征 动态性
//比如 api 接口请求地址 就是利用反射实现的
//根据url来的路径 来new相对应的对象
// 反射机制与面向对象中的封装性是不是矛盾的?如何看待两个技术
// 不矛盾
@Test
public void test3() throws ClassNotFoundException {
//class实例的理解
//调用 class
//方式一
Class<Person> c=Person.class
//方式二 通过运行时对象 调用
Person person=new Person()
Class person1=person.getClass()
//方式三 通过class 静态方法 获取 class
Class.forName("com.day14.json.Person")
}
//读取配置文件
@Test
public void test4() throws IOException {
//默认在当前module下的配置文件
Properties properties=new Properties()
// FileInputStream fis=new FileInputStream("jdbc.properties")
// properties.load(fis)
//classLoader 类的加载器 可以一层一层找 类的加载器
// 根据加载器的位置 找相对应的配置文件
//默认在src下的配置文件
ClassLoader classLoader=ClassLoaderTest.class.getClassLoader()
InputStream is=classLoader.getResourceAsStream("jdbc1.properties")
properties.load(is)
}
//体验反射的动态性
@Test
public void test5(){
int num=new Random().nextInt(3)
//根据运行 造相对应的类
String classPath
switch (num){
case 0:
classPath= "java.util.Date"
break
case 1:
classPath="java.lang.Object"
break
case 2:
classPath="com.day14.json.Person"
break
default:
throw new IllegalStateException("Unexpected value: " + num)
}
try {
Object object=new JsonTest().getInstance(classPath)
System.out.println(object)
} catch (Exception e) {
e.printStackTrace()
}
}
public Object getInstance(String classPath) throws Exception {
Class c=Class.forName(classPath)
return c.newInstance()
}
//获取当前运行时类的属性结构
@Test
public void test6(){
Class c= com.day14.json1.Person.class
//获取属性结构
//只能获取 当前运行时类及其父类中的公共的(Public)属性结构
Field[] fields = c.getFields()
for (Field f:fields){
System.out.println(f)
}
System.out.println("*****************")
//只能获取 当前运行时类属性结构 (不包含父类)
Field[] declaredFields = c.getDeclaredFields()
for (Field f:declaredFields){
System.out.println(f)
}
}
//权限修饰符 数据类型 变量名
@Test
public void test7(){
Class c= com.day14.json1.Person.class
Field[] declaredFields = c.getDeclaredFields()
for (Field f:declaredFields){
//权限修饰符
System.out.println(f.getModifiers())
System.out.println(Modifier.toString(f.getModifiers()))
// 数据类型
System.out.println(f.getType())
//变量名
System.out.println(f.getName())
}
}
//获取运行时类的方法结构
@Test
public void test8(){
Class c= com.day14.json1.Person.class
//获取当前运行时类及其父类的所有的公共方法
Method[] Methods = c.getMethods()
for (Method m:Methods){
System.out.println(m)
}
System.out.println("******************")
//获取当前运行时类的所有的方法(不包含父类)
Method[] declaredMethods = c.getDeclaredMethods()
for (Method m:declaredMethods){
System.out.println(m)
}
}
//获取运行时类的泛型的父类 和普通父类
@Test
public void test9(){
Class c= com.day14.json1.Person.class
// 普通父类 c.getSuperclass()
Type genericSuperclass = c.getGenericSuperclass()
System.out.println(genericSuperclass)
//获取父类的泛型的类型
ParameterizedType parameterizedType= (ParameterizedType) genericSuperclass
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments()
System.out.println(actualTypeArguments[0].getTypeName())
}
//获取运行时类的接口
//用的时候找
//获取运行时类的包
//用的时候找
//获取运行时类的注解
@Test
public void test10(){
//通过反射读取注释内容后 去做一些事情
Class c= com.day14.json1.Person.class
Annotation[] annotations = c.getAnnotations()
for (Annotation annotation:annotations){
System.out.println(annotation)
}
}
//调用运行时类的指定的结构 属性 方法 构造器
@Test
public void test11() throws NoSuchFieldException, IllegalAccessException, InstantiationException {
//通过反射读取注释内容后 去做一些事情
Class c= com.day14.json1.Person.class
Field id = c.getField("id")
System.out.println(id)
//声明对象
//Person person = (Person) c.newInstance()
//设置 对象中的 属性的值
// id.set(person,2123)
//获取对象中的 属性的值
// int id1= (int) id.get(person)
// System.out.println(id1)
//如果获取私有的
// Field name = c.getDeclaredField("name")
// //设置属性可访问的权限
// name.setAccessible(true)
// name.set(person,"json")
// name.get(person)
}
}