Use类
public class User {
private String name;
private double height;
private Date birthday;
public User(String name, double height, Date birthday) {
this.name = name;
this.height = height;
this.birthday = birthday;
}
public User() {
}
public String getName() {
return name;
}
public double getHeight() {
return height;
}
public Date getBirthday() {
return (Date) birthday.clone();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Double.compare(user.height, height) == 0 &&
name.equals(user.name) &&
birthday.equals(user.birthday);
}
@Override
public int hashCode() {
return Objects.hash(name, height, birthday);
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", height=" + height +
", birthday=" + new SimpleDateFormat("yyyy-MM-dd").format(birthday) +
'}';
}
}
首先介绍三种 获取类对象的方法
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd")//日期格式化对象
User tom = new User("Tom Galas",178.6,sdf.parse("1997-08-24"));
Class aClass = tom.getClass();//根据实例获取类对象
aClass = User.class;//根据类获取类对象
aClass = Class.forName("reflection.User");//根据类名(全限定名)获取类对象
特别注意:根据类名获取类对象 一定要使用全限定名,否则报
java.lang.ClassNotFoundException: User
获取到类之后我们就可以获取到类中的全部东西了。
首先来获取属性
Field[] allFields = aClass.getDeclaredFields();//可以获取包括private修饰的全部属性
Field[] publicFields = aClass.getFields();//只能获取public修饰的属性
for (Field field : allFields) {
//getType是获取属性的类型 getName是获取属性的变量名
System.out.println(field.getType() + "-->" + field.getName());
}
System.out.println("========================");
for (Field field : publicFields) {
System.out.println(field.getType() + "-->" + field.getName());
}
因为User类中的所有属性都是private修饰的,所以毫无疑问publicFields数组是空的
输出结果如下:
class java.lang.String–>name
double–>height
class java.util.Date–>birthday
========================
不单单是属性的类型和属性名,甚至连属性的修饰符都能够获取到
Field[] allFields = aClass.getDeclaredFields();//可以获取包括private修饰的全部属性
for (Field field : allFields) {
//getType是获取属性的类型 getName是获取属性的变量名
System.out.println(field.getModifiers() + "-->" + field.getType() + "-->" + field.getName());
}
运行结果:
2–>class java.lang.String–>name
2–>double–>height
2–>class java.util.Date–>birthday
会显示2,这是在Modifier类中规定的
下面抽取Modifier中一小段代码展示
/**
* The {@code int} value representing the {@code public}
* modifier.
*/
public static final int PUBLIC = 0x00000001;
/**
* The {@code int} value representing the {@code private}
* modifier.
*/
public static final int PRIVATE = 0x00000002;
/**
* The {@code int} value representing the {@code protected}
* modifier.
*/
public static final int PROTECTED = 0x00000004;
/**
* The {@code int} value representing the {@code static}
* modifier.
*/
public static final int STATIC = 0x00000008;
/**
* The {@code int} value representing the {@code final}
* modifier.
*/
public static final int FINAL = 0x00000010;
......
可以看出在源码中使用16进制来代表不同的修饰符的。
private是2。
我们要深知一点,在java中,一切都是对象。所以我们在Class中获取到的属性,方法等,他们也都是对象,在他们其中有编写好的操作他们的方法。
Constructor[] declaredConstructors = aClass.getDeclaredConstructors();//获取全部构造器
Annotation[] declaredAnnotations = aClass.getDeclaredAnnotations();//获取类上的全部注解(不是类中)
Method[] declaredMethods = aClass.getDeclaredMethods();//获取全部方法
还有许多方法可以前往Class类中查看。你会有很大收获。
许多方法的使用都大差不差。
在这里特别注意的是在Method中有个invoke方法
Method getName = aClass.getMethod("getName");//根据方法名获取方法对象
getName.invoke(tom);//调用tom实例中的getName方法,这里因为,getName没有参数,所以不需要传任何东西,如果有参数,则在tom后依次传入,使用标点隔开,如invoke(tom,1,2,3,..)
这里的getName方法不是static修饰的,所以需要传入User对象的一个实例,如果该方法是static修饰的,那么invoke的第一个参数直接传入null(注意是传入null,而不是不传)