*** 反射机制* @author JIANGJINGWEI* @create 2020-05-11-22:20*/
public class ReflectionTest1 {//反射之前,对Person的操作@Testpublic void test1(){//1.创建Person对象Person p1 = new Person("kite",123);//2.调用其属性和方法p1.age = 10;System.out.println(p1.toString());p1.show();//在Person类外部,不可以通过Person类的对象调用其内部私有结构。//比如:name、showNation()、以及私有构造器}//反射之后,对于Person的操作@Testpublic void test2() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {Class personClass = Person.class;//1.通过反射,创建Person对象Constructor cons = personClass.getConstructor(String.class, int.class);Object obj = cons.newInstance("Tom", 12);//这个Object对象其实还是Person,多态的体现Person p = (Person) obj;System.out.println(obj.toString());//Person{name='Tom', age=12}//2.通过反射,调用对象指定的属性、方法Field age = personClass.getDeclaredField("age");//调用属性age.set(p,10);System.out.println(p.toString());//调用方法Method show = personClass.getDeclaredMethod("show");show.invoke(p);//通过反射,可以调用Person类的私有结构。比如:私有构造器、私有属性和方法。Constructor cons1 = personClass.getDeclaredConstructor(String.class);cons1.setAccessible(true);Person p1 = (Person) cons1.newInstance("jake");System.out.println(p1);//调用私有属性Field name = personClass.getDeclaredField("name");name.setAccessible(true);name.set(p1,"jerry");System.out.println(p1);//调用私有的方法Method showNation = personClass.getDeclaredMethod("showNation", String.class);showNation.setAccessible(true);String nation = (String) showNation.invoke(p1, "中国");//相当于p1.showNation("中国");System.out.println(nation);//中国}//问题1:通过直接new方式或反射的方式都可以调用公共开发的结构,开发中用哪个?//建议:直接new的方式。//什么时候用反射的方式;反射的特征:动态性//问题2:反射机制与面向对象中的封装性是不是矛盾的?如何看待两个技术?//不矛盾。/*关于java.lang.Class类的理解1.类的加载过程:程序在经过javac.exe命令以后,会生成一个或多个字节码文件(.class结尾)。接着我们使用java.exe命令对某个字节码文件进行解释运行。相当于将某个字节码文件加载到内存中。此过程叫做类的加载。加载到内存中的类,我们就称为运行时类,此运行时类,就作为Class的一个实例。2.换句话说,Class的实例就对应着一个运行时类。3.加载到内存中的运行时类,会缓存一定的时间。在此时间之内,我们可以通过不同的方式来获取此运行时类*///获取Class实例的方式(前三中方式需要掌握,第三种最常使用)@Testpublic void test3() throws ClassNotFoundException {//方式一:调用运行时类的属性: .classClass<Person> clazz1 = Person.class;System.out.println(clazz1);//class java1.Person//方式二:通过运行时类的对象,调用getClassPerson p1 = new Person();Class clazz2 = p1.getClass();System.out.println(clazz2);//class java1.Person//方式三:调用Class的静态方法:forName(String classPath)Class clazz3 = Class.forName("java1.Person");System.out.println(clazz3);//class java1.PersonSystem.out.println(clazz1==clazz2);//trueSystem.out.println(clazz1==clazz3);//true//方式四:使用类的加载器:ClassLoaderClassLoader classLoader = ReflectionTest1.class.getClassLoader();Class clazz4 = classLoader.loadClass("java1.Person");System.out.println(clazz4);System.out.println(clazz1==clazz4);//true}//CLass实例可以是那哪些结构?@Testpublic void test4(){int[] a = new int[10];int[] b = new int[100];//只要数组的元素类型与维度一样,就是同一个ClassSystem.out.println(a.getClass()==b.getClass());//true}//万事万物皆对象?对象.xxx,File,URL,翻身,前端,数据库操作
}
/*** @author JIANGJINGWEI* @create 2020-05-11-22:21*/
public class Person {private String name;public int age;public Person(String name, int age) {this.name = name;this.age = age;}private Person(String name) {this.name = name;}public Person() {}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Person person = (Person) o;return age == person.age &&Objects.equals(name, person.name);}@Overridepublic int hashCode() {return Objects.hash(name, age);}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public void show(){System.out.println("nihao!!!");}private String showNation(String nation){System.out.println("nation:"+nation);return nation;}
}