阿里面试题

https://www.jianshu.com/p/21a0a2ae4af3

 

面试阿里P6,竟被MySQL难倒,再次二战,进入天猫团队(研发岗)   

Q:TCP客户端调用send方法向服务端发送信息三次,服务端接受几次?

Q:HTTPS是什么加密

 

Q:equals()和HashCode()深入理解?

A:https://blog.csdn.net/wonad12/article/details/78958411

Q:String,StringBuffer, StringBuilder 的区别是什么?String为什么是不可变的?

A:1、String是字符串常量,StringBuffer和StringBuilder都是字符串变量。后两者的字符内容可变,而前者创建后内容不可变。

2.在JDK中String类被声明为一个final类

3.StringBuffer是线程安全的,而StringBuilder是非线程安全的。(线程安全会带来额外的系统开销,所以StringBuilder的效率比StringBuffer高。如果对系统中的线程是否安全很掌握,可用StringBuffer,在线程不安全处加上关键字Synchronize)

Q:数组和链表的区别?

A:数组:内存中的一块连续区域,使用前要固定长度,申请内存空间(可能造成浪费),空间不够需重新定义(不利于扩展)

               带序号索引,用索引查询,查询效率高

                插入数据或删除数据时其后所有数据都有移位,插入删除效率低

  链表:内存中任何地方,不连续,无固定长度,随意增删(利于扩展)

            前一个数据存着下一个数据的地址,查询每次都是从头遍历,查询效率低

             插入或删除数据只需关注插入位置的前后元素,插入删除效率高   

Q:Vector,ArrayList, LinkedList,Stack的区别是什么?

A:Arraylist和Vector(synchronized方法-线程安全)数组方式存储数据,ArrayList在元素填满容器时会自动扩充容器大小的50%,而

Vector则是100%,因此ArrayList更节省空间

LinkedList(非线程安全)双向链表存储数据

Stack继承自Vector,后进先出(LIFO)的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置

Q:HashTable, HashMapTreeMap,ConcurrentH区别?

A:   HashTable线程同步,HashMap非线程同步。

       HashTable不允许<键,值>有空值,HashMap允许<键,值>有空值。

        HashTable使用Enumeration,HashMap使用Iterator。

        HashTable中hash数组的默认大小是11,增加方式的old*2+1,HashMap中hash数组的默认大小是16,增长方式一定是2的指数倍。

  TreeMap(非线程安全)默认是按键升序排序

ConcurrentHashMap线程安全,hashMap在多线程中put()可能引起死循环,采用分段锁技术

Q:try catch finally return语法糖?

A:1、不管有没有出现异常,finally块中代码都会执行;
2、当try和catch中有return时,finally仍然会执行;
3、finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,不管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的;
4、finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值

Q:WEB服务器,http服务器,应用服务器?

A:http服务器为WEB服务器的一种:apache

 应用服务器提供应用程序:tomcat(jsp,servlet)

Q:HTTP请求和响应?

http请求:(1)请求行:方法(GET和POST,DELETE、HEAD、OPTIONS、PUT、TRACE)+URL+http协议/版本

                    (2)请求头Accept,Cookie,Referer

                      (3空行)表明请求头结束

                     (4)请求体

http响应:(1)响应行:http协议/版本 状态码及描述

                    (2)响应头

                     (4)响应体

Q:GET,POST区别?
A:Get方式提交的数据最多1024字节,而Post则没有限制

Q:Session, Cookie区别

A:1、Session由应用服务器维护的一个服务器端的存储空间;Cookie是客户端的存储空间,由浏览器维护。

2、Session中保存的是对象,Cookie中保存的是字符串

Q:跨域?

A:JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象,同源政策,浏览器受限于同源政策

(A网站是一家银行,用户登录以后,又去浏览其他的网站B,如果网站B可以读取A网站的Cookie,会发生什么问题)

同源:协议相同  域名相同  端口相同

非同源限制范围:

(1)Cookie、LocalStorage和IndexDB无法获取。

  (2)DOM无法获得。

  (3)AJAX请求不能发送。

Q:servlet生命周期?

A:三个阶段(单实例多线程)

1.初始化:servlet容器启动,servlet对象初始化(内存分配空间),执行init()

2.响应请求:第一次请求servlet容器对servlet对象实例化(驻存于内存),调用service()方法,doGet(),doPost()

3.销毁:调用destory()

Q:StatementPreparedStatement的区别,什么是SQL注入,如何防止SQL注入
A:1、PreparedStatement支持动态设置参数,Statement不支持。

2、PreparedStatement可避免如类似 单引号 的编码麻烦,Statement不可以。

3、PreparedStatement支持预编译,Statement不支持。

4、在sql语句出错时PreparedStatement不易检查,而Statement则更便于查错。

5、PreparedStatement可防止Sql助于,更加安全,而Statement不行

什么是SQL注入: 通过sql语句的拼接达到无参数查询数据库数据目的的方法

SELECT * FROM user_table WHERE

username='' ;DROP DATABASE (DB Name) --' and password=''

过滤字符

Q:关于JAVA内存模型,一个对象(两个属性,四个方法)实例化100次,现在内存中的存储状态,几个对象,几个属性,几个方法。

A:由于JAVA中new出来的对象都是放在堆中,所以如果要实例化100次,将在堆中产生100个对象,一般对象与其中的属性、方法都属于一个整体,但如果         属性和方法是静态的,就是用static关键字声明的,那么属于类的属性和方法永远只在内存中存在一份

Q:JAVA常用异常?

A:异常分两大类Error和Exception,Exception分运行时异常(编译时不检验,代码异常),非运行异常(编译时即可检测出)

算术异常类:ArithmeticExecption

空指针异常类:NullPointerException

类型强制转换异常:ClassCastException

数组下标越界异常:ArrayIndexOutOfBoundsException

文件未找到异常:FileNotFoundException

字符串转换为数字异常:NumberFormatException
操作数据库异常:SQLException
输入输出异常:IOException
方法未找到异常:NoSuchMethodException

java.lang.NoClassDefFoundError 未找到类定义错误

java.lang.OutOfMemoryError 内存不足错误

Q:类加载机(ClassLoader)制?

A:将class文件加载到jvm虚拟机(.java文件是源码文件)

Bootstrap ClassLoader 最顶层的加载类,主要加载核心类库,%JRE_HOME%\lib下的rt.jar、resources.jar、charsets.jar和class等。另外需要注意的是可以通过启动jvm时指定-Xbootclasspath和路径来改变Bootstrap ClassLoader的加载目录。比如java -Xbootclasspath/a:path被指定的文件追加到默认的bootstrap路径中。我们可以打开我的电脑,在上面的目录下查看,看看这些jar包是不是存在于这个目录。
- Extention ClassLoader 扩展的类加载器,加载目录%JRE_HOME%\jre/lib\ext目录下的jar包和class文件。还可以加载-D java.ext.dirs选项指定的目录。
- Appclass Loader也称为SystemAppClass 加载当前应用的classpath的所有类

ClassLoader使用的是双亲委托模型来搜索类的,每个ClassLoader实例都有一个父类加载器的引用(不是继承的关系,是一个包含的关系),虚拟机内置的类加载器(Bootstrap ClassLoader)本身没有父类加载器,但可以用作其它ClassLoader实例的的父类加载器。当一个ClassLoader实例需要加载某个类时,它会试图亲自搜索某个类之前,先把这个任务委托给它的父类加载器,这个过程是由上至下依次检查的,首先由最顶层的类加载器Bootstrap ClassLoader试图加载,如果没加载到,则把任务转交给Extension ClassLoader试图加载,如果也没加载到,则转交给App ClassLoader 进行加载,如果它也没有加载得到的话,则返回给委托的发起者,由它到指定的文件系统或网络等URL中加载该类。如果它们都没有加载到这个类时,则抛出ClassNotFoundException异常

Q:类名.class, class.forName(), getClass()区别?

A:类名.class:JVM将使用类装载器, 将类装入内存(前提是:类还没有装入内存),不做类的初始化工作.返回Class的对象

Class.forName("类名字符串")  (注:类名字符串是包名+类名)  说明:装入类,并做类的静态初始化,返回Class的对象
实例对象.getClass()  说明:对类进行静态初始化、非静态初始化;返回引用运行时真正所指的对象(因为:子对象的引用可能会赋给父对象的引用变量中)所属的类的Class的对象

多线程部分

Q:多线程及其安全?

关键字:synchronized(同步互斥)  volatile(同步可见,保证变量对线程的可见,不保证线程安全)

主要类:Thread,

ThreadLocal(外部变量在线程内的本地存储),get(),set("")

ReenterantLock(重入锁作用同synchronized),lock(),unlock()

Condition(对象监视器),await(),signalAll()

Q:为什么volatile不能保证原子性而Atomic可以?

A:不要将volatile用在getAndOperate场合,仅仅set或者get的场景是适合volatile的,从Load到store到内存屏障(强制更新一次不同CPU的缓存),一共4步

AtomicXXX具有原子性和可见性:

Q:CAS是什么(只能保证一个共享变量的原子操作,解决ABA问题,改用传统的互斥同步可能会比原子类更高效)?

CAS是英文单词CompareAndSwap的缩写,中文意思是:比较并替换。CAS需要有3个操作数:内存地址V,旧的预期值A,即将要更新的目标值B。

CAS指令执行时,当且仅当内存地址V的值与预期值A相等时,将内存地址V的值修改为B,否则就什么都不做。整个比较并替换的操作是一个原子操作。

Q:什么是ABA问题?ABA问题怎么解决?

如果内存地址V初次读取的值是A,并且在准备赋值的时候检查到它的值仍然为A,那我们就能说它的值没有被其他线程改变过了吗?如果在这段期间它的值曾经被改成了B,后来又被改回为A,那CAS操作就会误认为它从来没有被改变过。这个漏洞称为CAS操作的“ABA”问题。Java并发包为了解决这个问题,提供了一个带有标记的原子引用类“AtomicStampedReference”,它可以通过控制变量值的版本来保证CAS的正确性

Q:wait()释放锁,sleep()不释放锁,notify()不释放锁(必须执行完notify()方法所在的同步synchronized代码块后释放锁)

Q:Thread.sleep唤醒以后是否需要重新竞争?Thread.Sleep(0)的作用?

A:是的。“触发操作系统立刻重新进行一次CPU竞争,重新计算优先级”。竞争的结果也许是当前线程仍然获得CPU控制权,也许会换成别的线程获得CPU控制权。这也是我们在大循环里面经常会写一句Thread.sleep(0) ,因为这样就给了其他线程比如Paint线程获得CPU控制权的权力,这样界面就不会假死在那里
Q:写一个单例?
// 第五种(静态内部类)线程安全:
class Singleton5{
    private static class SingletonHolder{
        private static Singleton5 instance=new Singleton5();
    }
    public Singleton5(){}
    public static Singleton5 getInstance(){
        return SingletonHolder.instance;
    }
}

//枚举单例满足线程安全、序列化等标准,枚举类本身就实现了单例

public enum Singleton6 {
    INSTANCE;
    public void method1(){
        System.out.println("cc");
    }
}

// 第七种(双重校验锁/双重锁懒汉模式(Double Check Lock))线程安全
class Singleton7{
    private volatile static Singleton7 instance;
    private Singleton7(){}
    public static Singleton7 getInstance(){
        if(instance==null){
            synchronized (Singleton7.class){
                if(instance==null){
                    instance=new Singleton7();
                }
            }
        }
        return instance;
    }
}

Q:并发工具包(java.util.concurent)下?

A:CountDownLatch计数器(Thread.join()的功能),new CountDownLatch(2),await() ,countDown()

CyclicBarrier同步屏障,让多个线程在达到同一屏障时等待,当所有线程都达到屏障时所有线程被唤起,new CyclicBarrier(2),await(),reset(),isBroken()

Semaphore控制并发线程数 ,new Semaphone(10),acquire(),release()

Exchanger成对线程间数据交换 exgr.exchange()

Q:为什么使用线程池?

A:new Thread()线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致死机或oom

缺乏更多功能,如定时执行、定期执行、线程中断

Java提供的四种线程池的好处在于:
a. 重用存在的线程,减少对象创建、消亡的开销,性能佳。
b. 可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。
c. 提供定时执行、定期执行、单线程、并发数控制等功能

newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行

FutureTask实现了Future和Runnable接口,Callable的call方法,不是异步执行的,是由Future的run方法调用

Callable<Integer> call = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                return 1;
            }
        };
        FutureTask<Integer> task = new FutureTask<>(call);
        new Thread(task).start();
        Integer result = task.get();

JVM部分

Q:JVM内存模型?

A:程序计数器,虚机栈stack,本地(方法)栈,java堆heap,方法区(非堆)(包括运行时常量)

Q:内存溢出OOM?

A:堆内存溢出 -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError        OutOfMemoryError  :Java heap space

虚机栈和本地方法栈溢出 -Xss128k  StackOverflowError

方法区和运行时常量池溢出 -XX:PermSize=10M -XX:MaxPermSize=10m   OutOfMemoryError  :PermGen space

 

Mysql部分

Q:Mysql逻辑架构?

A:链接处理,优化工具功能,存储引擎(数据库)

Q:Mysql存储引擎?

A:InnoDB 支持事务,行级锁,外键;聚簇索引数据结构(B+TREE)

MyISAM 不支持事务,不支持行级锁(有表锁),不支持外键;非聚簇索引数据结构(B+TREE)

Memory hash索引

Q:最左前缀原则?or 用单列索引

Q:where [ ] group by [ 列名] having [ 聚合函数]  order by [列名] limit 1,10

group by 会走索引

order by 的字段在where字句中才会走索引

Q:隔离级别(定义哪些操作在事务内外的可见性)?

A:read uncommitted(未提交读/脏读问题),read committed(提交读/不可重复读问题(一个事务内两个相同查询返回不同数据,update操作引起)),mysql默认:repeatable read(重复读(不允许其他事务update)/幻读问题(insert引起)),serializable序列化

Q:数据库三范式?

A:第一范式:当关系模式R的所有属性都不能在分解为更基本的数据单位时,称R是满足第一范式的,简记为1NF。(每一列属性都是不可再分,相似列尽量合并不冗余)

第二范式:如果关系模式R满足第一范式,并且R得所有非主属性都完全依赖于R的每一个候选关键属性,称R满足第二范式,简记为2NF。(每一行的数据只能与其中一列相关)

第三范式:设R是一个满足第一范式条件的关系模式,X是R的任意属性集,如果X非传递依赖于R的任意一个候选关键字,称R满足第三范式,简记为3NF(数据不能存在传递关系 id->所在公司->公司地址)

SPRING 部分

Q:spring事务传播特性?

A:事务传播行为就是多个事务方法相互调用时,事务如何在这些方法间传播。spring支持7种事务传播行为

propagation_requierd:如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,这是最常见的选择。
propagation_supports:支持当前事务,如果没有当前事务,就以非事务方法执行。
propagation_mandatory:使用当前事务,如果没有当前事务,就抛出异常。
propagation_required_new:新建事务,如果当前存在事务,把当前事务挂起。
propagation_not_supported:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
propagation_never:以非事务方式执行操作,如果当前事务存在则抛出异常。
propagation_nested:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与propagation_required类似的操作

Q:什么是控制反转(IOC)?什么是依赖注入(DI)?

A:bean的管理由spring的ioc容器实现,依赖注入是实现控制反转的方式

Q:BeanFactory和ApplicationContext有什么区别?

A:ApplicationContext(应用上下文,接口,实现:FileSystemXmlApplicationContext,ClassPathXmlApplicationContext,)是BeanFactory(spring的最核心接口)的继承

BeanFactory是懒加载,ApplicationContext是在容器启动时,一次性创建

ApplicationContext做了拓展:

MessageSource(国际化资源接口)、

ResourceLoader(资源加载接口)ctx. getResource(“classpath:config.properties”)、

ApplicationEventPublisher(应用事件发布接口)

Q:Spring支持的几种bean的作用域?

A:Spring框架支持以下五种bean的作用域:

singleton : bean在每个Spring ioc 容器中只有一个实例。
prototype:一个bean的定义可以有多个实例。
request:每次http请求都会创建一个bean,该作用域仅在基于web的Spring ApplicationContext情形下有效。
session:在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
global-session:在一个全局的HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效

Q:几种注入方式?几种自动装配方式?

A:接口,构造器,setter;

Q:Spring中注入一个null 和一个空字符串吗?

A:可以

Q:@Resource和@Autowired?

A:前者根据名字name(默认)或类型type注入,后者根据类型注入

Q:AOP?

A:spring aop的实现是基于java的代理机制
切面(Aspect):对象操作过程中的截面
连接点(Join point)对象操作过程中的某个阶段点
切入点(Point)连接点的集合
通知(Advice)某个切入点被横切后所采取的处理逻辑;五种类型的通知:before,after,after-returning,after-throwing,around

目标对象(Target)所有被通知的对象(被代理对象)
织入(Weaving)将切面功能应用到目标对象的过程。由代理工厂创建一个代理对象,这个代理可以为目标对象执行切面功能

Q:SPU和SKU?

A:SPU全称Standard Product Unit (标准化产品单元)。译为:最小包装单元

SKU全称stock keeping unit(库存量单位)。译为:最小主要单元

 

①ArrayList 通过数组实现,一旦我们实例化 ArrayList 无参数构造函数默认为数组初始化长度为 10②add 方法底层实现如果增加的元素个数超过了 10 个,那么 ArrayList 底层会新生成一个数组,长度为原数组的 1.5 倍+1,然后将原数组的内容复制到新数组当中,并且后续增加的内容都会放到新数组当中。当新数组无法容纳增加的元素时,重复该过程。是一旦数组超出长度,就开始扩容数组。扩容数组调用的方法 Arrays.copyOf(objArr, objArr.length + 1);

LinkedList 底层的数据结构是基于双向循环链表的,既然是双向链表,那么必定存在一种数据结构——我们可以称之为节点,节点实例保存业务数据,前一个节点的位置信息和后一个节点位置信息

 

HashSet的底层实现是通过Map来实现的,Set中不允许有重复的元素,类似于集合,在HashSet的实现的时候,通过Map来实现,每次往Set里添加数据,都会将数据设置为Map的键值,Map的值设置一个默认值,因为Map的键值不能重复,所以每次添加到Set内的数据也不能重复

HashMap由数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的。如果定位到的数组位置不含链表(当前entry的next指向null),那么对于查找,添加等操作很快,仅需一次寻址即可;如果定位到的数组包含链表,对于添加操作,其时间复杂度依然为O(1),因为最新的Entry会插入链表头部,急需要简单改变引用链即可,而对于查找操作来讲,此时就需要遍历链表,然后通过key对象的equals方法逐一比对查找。所以,性能考虑,HashMap中的链表出现越少,性能才会越好

initialCapacity loadFactor

Hashmap的扩容需要满足两个条件:当前数据存储的数量(即size())大小必须大于等于阈值;当前加入的数据是否发生了hash冲突

corePoolSize:核心线程数,默认情况下核心线程会一直存活,即使处于闲置状态也不会受存keepAliveTime限制。除非将allowCoreThreadTimeOut设置为true。

maximumPoolSize:线程池所能容纳的最大线程数。超过这个数的线程将被阻塞。当任务队列为没有设置大小的LinkedBlockingDeque时,这个值无效。keepAliveTime:非核心线程的闲置超时时间,超过这个时间就会被回收。

Unit:指定keepAliveTime的单位,如TimeUnit.SECONDS。当将allowCoreThreadTimeOut设置为true时对corePoolSize生效。

workQueue:线程池中的任务队列.常用的有三种队列SynchronousQueue,LinkedBlockingDeque,ArrayBlockingQueue。

threadFactory:线程工厂,提供创建新线程的功

 

Q:NIO?

SocketChannel channel=SocketChannel.open();
channel.configureBlocking(false);
channel.connect(new InetSocketAddress("127.0.0.1",8080));
if(channel.finishConnect()){
    ByteBuffer buf=ByteBuffer.allocate(1024);
    buf.clear();
    buf.put("这是来自nioClient的请求".getBytes());
    buf.flip();
    while (buf.hasRemaining()) {
        channel.write(buf);
    }
}
channel.close();
selector= Selector.open();
ssc= ServerSocketChannel.open();
ssc.configureBlocking(false);
ssc.socket().bind(new InetSocketAddress(8888));
ssc.register(selector, SelectionKey.OP_ACCEPT);
while(true){
    if(selector.select(3000)==0){
        System.out.println("==");
        continue;
    }
    Iterator<SelectionKey> iter=selector.selectedKeys().iterator();
    while(iter.hasNext()){
        SelectionKey key=iter.next();
        if (key.isAcceptable()) {
        }
        if (key.isReadable()) {
        }
        if (key.isWritable() && key.isValid()) {
        }
        if (key.isConnectable()) {
        }
        iter.remove();
    }
}

RandomAccessFile rfile = new RandomAccessFile("F:\\java_code\\jdk8_api\\src\\main\\resources\\in.txt", "r");
            RandomAccessFile wfile = new RandomAccessFile("F:\\java_code\\jdk8_api\\src\\main\\resources\\nio_out.txt", "rw");
            FileChannel channel = rfile.getChannel();
            FileChannel channel1 = wfile.getChannel();
            channel.transferTo(0,channel.size(),channel1);
            channel.close();
            channel1.close();

 

Class class1=Reflect.class;
System.out.println(class1);//class com.fcc.jdk8api.core.reflect.Reflect
Class class2=new Reflect().getClass();
System.out.println(class2);//class com.fcc.jdk8api.core.reflect.Reflect
System.out.println(class2.getName());//com.fcc.jdk8api.core.reflect.Reflect
System.out.println(class1==class2);//true


System.out.println(class1.getPackage());//Package  getPackage()获取此类的包
System.out.println(class1.getSuperclass());//


//构造方法
//Constructor<?>[]     getDeclaredConstructors()返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。
Constructor[] constructorArr=class1.getConstructors();
for(int i=0;i<constructorArr.length;i++){
    System.out.println(constructorArr[i].toString());
}
//Constructor<T>   getDeclaredConstructor(Class<?>... parameterTypes)返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。
Constructor constructor=class1.getDeclaredConstructor(String.class);
Reflect reflect=(Reflect)constructor.newInstance("fcc");
//Annotation[][]   getParameterAnnotations()
//          按照声明顺序返回一组数组,这些数组表示通过此 Constructor 对象表示的方法的形参上的注释。
constructor.getParameterAnnotations();




//成员变量
//Field[]  getFields()返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共(public)字段
//Field[]  getDeclaredFields()返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。
System.out.println(class1.getDeclaredFields());
Field[] declaredFields=class1.getDeclaredFields();
for(int i=0;i< declaredFields.length;i++){
    System.out.println(declaredFields[i].toString());
}

//方法
//Method   getDeclaredMethod(String name, Class<?>... parameterTypes)
// 返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。
Method method= class1.getDeclaredMethod("method1", String.class);
System.out.println(method);
System.out.println(method.getName());
//AccessibleObject 类是 Field、Method 和 Constructor 对象的基类
// 值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查
method.setAccessible(true);
method.invoke(new Reflect(),"20");

 

Record record=new Record();
System.out.println(record.getClass().getModifiers());
Annotation[] annotations=record.getClass().getDeclaredAnnotations();
Annotation annotation=record.getClass().getDeclaredAnnotation(MyAnnotation.class);
for(int i=0;i<annotations.length;i++){
    System.out.println(annotations[i].toString());
}
//  boolean    isAnnotation()
//          如果此 Class 对象表示一个注释类型则返回 true。
System.out.println(record.getClass().isAnnotation());
System.out.println(annotation.getClass().isAnnotation());
System.out.println(MyAnnotation.class.isAnnotation());
//  boolean    isAnnotationPresent(Class<? extends Annotation> annotationClass)
//          如果指定类型的注释存在于此元素上,则返回 true,否则返回 false。
System.out.println(record.getClass().isAnnotationPresent(MyAnnotation.class));
System.out.println(annotation.annotationType());
System.out.println(annotation.getClass());
System.out.println(((MyAnnotation) annotation).value());
System.out.println(((MyAnnotation) annotation).value());

//  int    getModifiers()
//          以整数形式返回由此 Field 对象表示的字段的 Java 语言修饰符。
System.out.println(record.getClass().getDeclaredField("name").getModifiers());//2
if(record.getClass().getDeclaredField("name").isAnnotationPresent(MyAnnotation.class)){
    //Object   get(Object obj)
    //          返回指定对象上此 Field 表示的字段的值。
    System.out.println(record.getClass().getDeclaredField("name").get(record));//feicong
    System.out.println(record.getClass().getDeclaredField("name").getAnnotation(MyAnnotation.class).value());//fcc
}



Constructor constructor=record.getClass().getDeclaredConstructor(String.class);
Record record1=(Record)constructor.newInstance("fcc11");
//Annotation[][]   getParameterAnnotations()
//          按照声明顺序返回一组数组,这些数组表示通过此 Constructor 对象表示的方法的形参上的注释。
Annotation[][] parameterAnnotations1=constructor.getParameterAnnotations();
for(int i=0;i<parameterAnnotations1.length;i++){
    int len=parameterAnnotations1[i].length;
    System.out.println("i= "+i);
    for(int k=0;k<len;k++){
        MyAnnotation annotation1= (MyAnnotation)parameterAnnotations1[i][k];
        System.out.println(annotation1.value());
        System.out.println(annotation1.num());
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值