1、类对象和对象的区别?
假设,我们有如下类:
public class Hero {
public String name;
public float hp;
public int damage;
public int id;
static String copyright;
static {
System.out.println("初始化 copyright");
copyright = "版权由Riot Games公司所有";
}
}
我们用如下语句创建对象和类对象:
Hero h1 = new Hero();
Hero h2 = new Hero();
Class c = Hero.class;
h1和h2都是Hero对象,c是类对象。一个类只有一个类对象,类对象之间的不同主要体现在它们之间有不同的成员变量和方法。
2、获取类对象的三种方式
Class c1 = Hero.class;
Class c2 = Class.forName;
Class c3 = new Hero.getClass();
在一个jvm中一个类只会有一个类对象存在,也就是说c1 == c2 ==c3
3、利用类对象来创建一个对象
package reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Hero {
public String name;
public float hp;
public int damage;
public int id;
static String copyright;
static {
System.out.println("初始化 copyright");
copyright = "版权由Riot Games公司所有";
}
public Hero(String name) {
this.name = name;
}
public static void main(String[] args) {
try {
Class c = Class.forName("reflection.Hero");
Constructor constructor = c.getConstructor(String.class);
Hero hero = (Hero) constructor.newInstance("hh");
System.out.println(hero.name);
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
4、使用配置文件获取类对象
package reflection;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;
public class Hero {
public String name;
public float hp;
public int damage;
public int id;
static String copyright;
static {
System.out.println("初始化 copyright");
copyright = "版权由Riot Games公司所有";
}
public void study() {
System.out.println("good good study day day up");
}
public static void main(String[] args) {
try {
Properties properties = new Properties();
FileInputStream fileInputStream = new FileInputStream("config/test.properties");
properties.load(fileInputStream);
Class z = Class.forName(properties.getProperty("classname"));
Object obj = z.newInstance();
Constructor constructor = z.getConstructor();
String methodname = properties.getProperty("methodname");
Method method = z.getMethod(methodname);
method.invoke(obj);
} catch (ClassNotFoundException | IOException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
test.properties文件
classname=reflection.Hero
methodname=study
5、反射有什么用?
假设我们有两个业务Service1和Service2
public class Service1 {
public void work() {
//do something
}
}
public class Service2 {
public void work() {
//do something
}
}
我们使用Service1:
public static void main(String[] args) {
Service1 s1 = new Service1();
s1.work();
}
如果我们这时候改用Service2,我们需要改变原有代码:
public static void main(String[] args) {
//Service1 s1 = new Service1();
//s1.work();
Service2 s2 = new Service2();
s2.work();
}
但是如果我们使用反射来实现,那么我们就可以只修改配置文件里的内容将就可以。