测试类
package com.liaoxiang.java1;
@MyAnnotation(value="rose")
public class Person extends Creature<String> implements Comparable,MyInterface{
public String name;
private Integer age;
int id;
//省略getter、settter
public Person() {
System.out.println("调用了Person的空参构造器");
}
public Person(String name){
this.name = name;
}
private Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", id=" + id +
'}';
}
@Override
public int compareTo(Object o) {
return 0;
}
@MyAnnotation(value = "jack")
public void show(){
System.out.println("我是一个人!");
}
private Integer display(String nation, Integer i) throws Exception{
System.out.println("我的国籍是:"+ nation);
return i;
}
public static void info(){
System.out.println("静态方法:我是一个中国人");
}
// 内部类
class Bird{}
}
通过反射创建一个类,并调用其中的方法、属性
/**
* 通过反射创建一个类,并调用其中的方法、属性
*/
@Test
public void test2() throws Exception {
Class<Person> clazz = Person.class;
// 1、创建clazz对应的运行时类Person类的对象
Person person = clazz.newInstance();
System.out.println(person);
// 2、通过反射调用运行时类的指定的属性,public修饰的属性
Field f1 = clazz.getField("name");
f1.set(person, "LiuDeHua");
System.out.println(person);
// private修饰的属性
Field f2 = clazz.getDeclaredField("age");
f2.setAccessible(true);
f2.set(person, 20);
System.out.println(person);
// 3、通过反射调用运行时类的指定的方法,调用person的show()方法
Method m1 = clazz.getMethod("show");//没有形参的情况
m1.invoke(person);
Method m2 = clazz.getDeclaredMethod("display", String.class,Integer.class);// 有形参的情况
m2.setAccessible(true);
Object o = m2.invoke(person, "CHN", 10);// 执行display()方法,返回值为display()方法的返回值
System.out.println(o);
}
执行结果:
调用了Person的空参构造器
Person{name='null', age=null, id=0}
Person{name='LiuDeHua', age=null, id=0}
Person{name='LiuDeHua', age=20, id=0}
我是一个人!
我的国籍是:CHN
10
获取Class类的实例的三个方法
/**
* 获取Class类的实例的三个方法
* 1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
* 多用于配置文件,将类名定义在配置文件中。读取文件,加载类
* 2. 类名.class:通过类名的属性class获取
* 多用于参数的传递
* 3. 对象.getClass():getClass()方法在Object类中定义着
* 多用于对象的获取字节码的方式
* 结论:
* 同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个
*/
@Test
public void test3() throws ClassNotFoundException {
// 1、调用运行时类本身的.class属性: 类名.class
Class<Person> personClass = Person.class;
Class<String> stringClass = String.class;
System.out.println("1: "+personClass.getName());
System.out.println("1: "+stringClass.getName());
// 2、通过运行时类的对象获取: 对象.getClass()
Person person = new Person();
Class<? extends Person> aClass = person.getClass();
System.out.println("2: "+aClass.getName());
// 3、通过Class的静态方法: Class.forName("全类名")
String className = "com.liaoxiang.java1.Person";
Class<?> aClass1 = Class.forName(className);
System.out.println("3: "+aClass1);
// 4、通过类的加载器
ClassLoader classLoader = this.getClass().getClassLoader();
Class<Person> aClass2 = (Class<Person>) classLoader.loadClass(className);
System.out.println("4: " + aClass2.getName());
System.out.println(personClass == aClass);
System.out.println(personClass == aClass1);
System.out.println(personClass == aClass2);
}
执行结果:
1: com.liaoxiang.java1.Person
1: java.lang.String
调用了Person的空参构造器
2: com.liaoxiang.java1.Person
3: class com.liaoxiang.java1.Person
4: com.liaoxiang.java1.Person
true
true
true
关于类加载器
/**
* 类加载器:将一个类加载进内存
*/
public class ClassLoaderTest {
@Test
public void test() throws Exception {
// 获取系统类加载器
ClassLoader loader1 = ClassLoader.getSystemClassLoader();
System.out.println(loader1);
// 获取扩展类加载器
ClassLoader loader2 = loader1.getParent();
System.out.println(loader2);
// 获取引导类加载器 null 获取不到
ClassLoader loader3 = loader2.getParent();
System.out.println(loader3);
// 获取加载Person的加载器
Class clazz1 = Person.class;
ClassLoader loader4 = clazz1.getClassLoader();
System.out.println(loader4);
// 核心类库的加载器为引导类加载器 获取不到
String className = "java.lang.String";
Class clazz2 = Class.forName(className);
ClassLoader loader5 = clazz2.getClassLoader();
System.out.println(loader5);
/**
* 掌握如下用法:
*/
//法一:加载当前包下的文件
ClassLoader loader = this.getClass().getClassLoader();
InputStream is = loader.getResourceAsStream("com/liaoxiang/java1/test.properties");
//法二:加载当前工程下的文件
//FileInputStream is = new FileInputStream(new File("test2.properties"));
Properties pros = new Properties();
pros.load(is);
String name = pros.getProperty("user");
System.out.println(name);
String password = pros.getProperty("password");
System.out.println(password);
}
执行结果:
sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$ExtClassLoader@a09ee92
null
sun.misc.Launcher$AppClassLoader@18b4aac2
null
root
123456
}
test.properties
user=root
password=123456