第十四章 类型信息

类是程序的一部分,每个类都有一个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

通过反射可以调用类的私有方法。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值