反射
获取反射对象:
三种获取Class类型的对象
三种方式获取反射对象:
对象类:
package JavaAPI.FanShe.Test1.ch01;
import java.util.Objects;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
测试类:
package JavaAPI.FanShe.Test1.ch01;
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
/**
* 使用 对象.class 获取对象位置
* 使用方便
*/
Class<Student> c1 = Student.class;
System.out.println(c1);
Class<Student> c2 = Student.class;
System.out.println(c2); //说明编译时只会生成一次字节码文件
System.out.println("--------");
/**
* 使用 对象.getClass() 方式获取对象位置
*/
Student s=new Student();
Class<? extends Student> c3 = s.getClass();
System.out.println(c3);
System.out.println("--------");
/**
* 使用 forName() 方式获取对象位置
* 可以配置到文件中,修改方便
*/
Class<?> c4 = Class.forName("JavaAPI.FanShe.Test1.ch01.Student");
System.out.println(c4);
}
}
反射获取构造方法并使用:
获取多个构造方法:
有两种常用的方法可以获取多个构造方法:
1.getConstructors(Class):获取所有的公共的构造方法,返回一个Constructor集合
2.getDeclaredConstructors(Class):获取所有的构造方法,返回一个Constructor集合
不同包下的对象:
学生类:
package JavaAPI.FanShe.Test1.ch01;
import java.util.Objects;
public class Student {
private String name;
private int age;
public Student() {
}
private Student(String name){
this.name = name;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
public void show1(){
}
private void show2(){
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
测试类:
package JavaAPI.FanShe.Test1.ch02;
import JavaAPI.FanShe.Test1.ch01.Student;
import java.lang.reflect.Constructor;
public class Test {
public static void main(String[] args) {
//获取反射对象
Class<Student> c = Student.class;
/**
* getConstructors()
* 获取公共的构造方法
*/
Constructor<?>[] cs1 = c.getConstructors();
for (Object o:cs1)
System.out.println(o);
System.out.println("---------------");
/**
* 获取所有的构造方法
* getDeclaredConstructors()
*/
Constructor<?>[] cs2 = c.getDeclaredConstructors();
for (Object o:cs2)
System.out.println(o);
}
}
获取单个构造方法并创建对象:
两种方法获取单个对象
getConstructor(Class) :获取单个公共的对象
getDeclaredConstructor(Class) :获取单个所有可指定类型的对象
使用newInstance(参数):可以使用获取到的构造方法创建对象
示例:
学生类:
package JavaAPI.FanShe.Test1.ch01;
import java.util.Objects;
public class Student {
private String name;
private int age;
public Student() {
}
private Student(String name){
this.name = name;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
public void show1(){
}
private void show2(){
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
测试类:
package JavaAPI.FanShe.Test1.ch02;
import JavaAPI.FanShe.Test1.ch01.Student;
import java.lang.reflect.Constructor;
/**
* 反射获取单个构造方法
*/
public class Test2 {
public static void main(String[] args) throws Exception {
/**
* 获取对象的路径信息
*/
Class<?> c = Class.forName("JavaAPI.FanShe.Test1.ch01.Student");
/**
* 查看一下该对象中所有的构造方法
*/
Constructor<?>[] con = c.getDeclaredConstructors();
for (Object o:con)
System.out.println(o);
/**
* 获取对象单个无参构造的对象
*/
Constructor<?> c1 = c.getConstructor();
System.out.println("获取到的公共无参构造方法为:"+c1);
/**
*使用newInstance()创建对象
*/
Object s1 = c1.newInstance();
System.out.println("创建的对象为:"+s1);
System.out.println("---------");
/**
* 获取对象单个带参构造方法
*/
Constructor<?> c2 = c.getConstructor(String.class, int.class);
System.out.println("获取到的公共带参构造方法为:"+c2);
/**
* 使用newInstance()创建对象并赋值
*/
Student s2 = (Student)c2.newInstance("小明",15);
System.out.println("创建的对象为:"+s2);
System.out.println("---------");
Constructor<?> c3 = c.getDeclaredConstructor(String.class);
System.out.println("获取到的私有带参构造方法为:"+c3);
Object s3 = c3.newInstance("小王");
System.out.println("创建的对象为:"+s3);
}
}
可以看到,最后一种方式报错,是因为私有构造方法不能创建对象,但是在反射中,可以使用暴力反射来构造对象
setAccessible(true),暴力反射使虚拟机取消访问检查
示例:
Constructor<?> c3 = c.getDeclaredConstructor(String.class);
c3.setAccessible(true); //暴力反射
System.out.println("获取到的私有带参构造方法为:"+c3);
Object s3 = c3.newInstance("小王",15);
System.out.println("创建的对象为:"+s3);