类是程序的一部分,每个类都有一个Class对象。换言之,每当编写并且编译了一个新类,就会产生一个Class对象,
为了使用类而做的准备工作实际包含三个步骤:
1、加载,这是由类加载器执行的。该步骤将查找字节码(通常在classpath所置顶的路劲中查找,单这并非是必需的),并从这些字节码中创建一个Class对象。
2、连接,在连接阶段将验证类中的字节码,为静态域分配存储空间,并且如果必需的话,将解析这个类创建的对其他类的所有引用。
3、初始化,如果该类具有超类,则对其初始化,执行静态初始化器和静态初始化块。
使用.class语法来获得对类的引用不会引发初始化。但是为了产生Class引用,Class.ForName()立即就进行了初始化。
Class引用表示的就是他所指向的对象的确切类型,而该对象便是Class类的一个对象。
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import javax.management.RuntimeErrorException;
class CountedInteger{
private static long counter;
private final long id=counter++;
public String toString(){
return Long.toString(id);
}
}
class Person{
private String name;
private int age;
public void printSelf(){
System.out.println(name+"---"+age);
}
}
class Student extends Person{
private String className;
public void printClassName(){
System.out.println(className);
}
}
public class FilledList<T>{
private Class<T> type;
public FilledList(Class<T> type){
this.type=type;
}
public List<T> create(int nElements){
List<T> result=new ArrayList<T>();
try{
for(int i=0;i<nElements;i++){
result.add(type.newInstance());
}
}catch(Exception e){
throw new RuntimeException(e);
}
return result;
}
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
FilledList<CountedInteger> fl=new FilledList<>(CountedInteger.class);
System.out.println(fl.create(15));
ArrayList<String> strs=new ArrayList<String>();
Class<Student> studentClass=Student.class;
Student s = studentClass.newInstance();
s.printClassName();
s.printSelf();
Class<? super Student> personClass=studentClass.getSuperclass();
// Class<Person> personClass2=studentClass.getSuperclass();
Object o=personClass.newInstance();
}
}
打印结果是
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
null
null---0
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
class MethodSelector implements InvocationHandler{
private Object proxied;
public MethodSelector(Object proxied){
this.proxied=proxied;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.getName().equals("interesting")){
System.out.print("aaaaa");
}
return method.invoke(proxied, args);
}
}
interface SomeMethods{
void boring1();
void boring2();
void interesting(String arg);
}
class Inplementation implements SomeMethods{
@Override
public void boring1() {
System.out.println("boring1");
}
@Override
public void boring2() {
System.out.println("boring2");
}
@Override
public void interesting(String arg) {
System.out.println("interesting==>"+arg);
}
}
public class SelectingMethods {
public static void main(String[] args) {
SomeMethods proxy=(SomeMethods) Proxy.newProxyInstance(
SomeMethods.class.getClassLoader(),
new Class[]{SomeMethods.class},
new MethodSelector(new Inplementation()));
proxy.boring1();
proxy.boring2();
proxy.interesting("bbbbbbbbbbb");
}
}
这是一个动态代理的实现,打印结果是
boring1
boring2
aaaaainteresting==>bbbbbbbbbbb
import java.lang.reflect.Method;
public class TestInvoke {
public static void main(String[] args) throws Exception {
AA a=HiddenC.makeAA();
a.f();
Method m=a.getClass().getDeclaredMethod("p");
m.setAccessible(true);
m.invoke(a);
}
}
interface AA{
void f();
}
class CC implements AA{
@Override
public void f() {
System.out.println("ffffffff");
}
private void p(){
System.out.println("ppppppp");
}
}
class HiddenC{
public static AA makeAA(){
return new CC();
}
}
打印出
ffffffff
ppppppp
通过反射可以调用类的私有方法。