• 关于

    Joda-Time

    的搜索结果

回答

这个的原因是Classpath中依赖的Joda-time版本过低导致,joda-time的低版本在Java8上会有这个bug。可以选择更新到ots-public的最新版本2.2.4来解决这个问题,若你自己也依赖了joda-time库,需要提升到2.9.

木洛 2019-12-02 02:14:13 0 浏览量 回答数 0

回答

原因 Classpath中依赖的Joda-time版本过低,joda-time的低版本在Java 8上会出现此类错误。 解决方案 可以更新到ots-public的最新版本2.2.4来解决这个问题。如果您也依赖了joda-time库,需要提升到2.9。

保持可爱mmm 2020-03-29 15:36:21 0 浏览量 回答数 0

问题

Java SDK报错:Invalid date format

云栖大讲堂 2019-12-01 21:03:41 1337 浏览量 回答数 0

阿里云高校特惠,助力学生创业梦!0元体验,快速入门云计算!

学生动手场景应用,快速了解并掌握云服务器的各种新奇玩法!

回答

首先,因为你得到的日期没有一天的时间,你应该更喜欢乔达时间的LocalDate过度DateTime。 其次,构造函数接受的格式(也包括LocalDate构造函数)是国际标准ISO 8601。我应该说,建议您的客户在他们的请求中使用此格式会很不错。 但是,如果您坚持要使用:使用格式化程序将请求中的字符串解析为LocalDate。 DateTimeFormatter dateFormatter = DateTimeFormat.forPattern("dd-MM-yyyy"); String requestDateOfBirth = "12-12-2012"; LocalDate dateOfBirth = LocalDate.parse(requestDateOfBirth, dateFormatter); System.out.println("Date of birth: " + dateOfBirth); 该代码段的输出为: 生日:2012-12-12 在12-12-2012我不知道这是一个月的一天,这是一个月,但你可以换dd为一个月的一天,MM如果需要一个月格式模式字符串。 最后,如果这是新代码,则您可能更喜欢使用Java.time(现代Java日期和时间API)而不是Joda-Time。Joda-Time项目的官方建议说要迁移。 链接 Oracle教程:Date Time说明如何使用java.time。 维基百科文章:ISO 8601 回答来源:Stack Overflow

montos 2020-03-25 21:21:03 0 浏览量 回答数 0

问题

使用excel插件的时候报错,import org.codehaus.groov?报错

爱吃鱼的程序员 2020-06-22 11:08:35 0 浏览量 回答数 1

回答

先把String转成Date再转Timestamp,使用joda可以让转换更简单。 import org.joda.time.DateTime; import java.sql.Timestamp; public class Q1010000002719435 { public static void main(String[] args) { String timeStampString = "2014-11-11"; DateTime dateTime = DateTime.parse(timeStampString); Timestamp timestamp = new Timestamp(dateTime.getMillis()); System.out.println(timestamp); } }

蛮大人123 2019-12-02 01:53:55 0 浏览量 回答数 0

问题

ClassNotFoundException:java.net.http.HttpClient

montos 2020-03-27 13:29:06 1 浏览量 回答数 1

问题

storm 0.96启动失败了? 400 报错

爱吃鱼的程序员 2020-06-01 13:27:45 0 浏览量 回答数 1

问题

惠州开诊断证明-rxq

游客5k2abgdj3m2ti 2019-12-01 22:09:10 3 浏览量 回答数 0

问题

为什么最多的java.util.Date方法不推荐使用?

游客bnlxddh3fwntw 2020-04-23 20:54:25 4 浏览量 回答数 1

问题

在EMR类中找不到Spark-submit异常java

小六码奴 2019-12-01 19:38:43 418 浏览量 回答数 1

回答

版本低了,更新版本 joda-time

a560a0b625d 2020-03-30 20:56:27 0 浏览量 回答数 0

回答

经过摸索,终于发现病灶....改太急.... @BeanpublicThemeSourcemessageSource(){ResourceBundleThemeSourcemessageSource=newResourceBundleThemeSource();if(StringUtils.hasText(this.basename)){messageSource.setBasenamePrefix(trimAllWhitespace(this.basename));}returnmessageSource;} 改为 @BeanpublicThemeSourcethemeSource(){ResourceBundleThemeSourcethemeSource=newResourceBundleThemeSource();if(StringUtils.hasText(this.basename)){themeSource.setBasenamePrefix(trimAllWhitespace(this.basename));}returnthemeSource;} 就好了 明天将日志和配置贴上来得把你配置发出来,看起来像是什么配置有问题 日志 2015-07-0809:29:07.611DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Exposingrequestattribute'base'withvalue[http://localhost:8080]tomodel2015-07-0809:29:07.612DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'message'oftype[java.lang.String]torequestinviewwithname'common/test.html'2015-07-0809:29:07.612DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'request'oftype[org.springframework.web.servlet.support.RequestContext]torequestinviewwithname'common/test.html'2015-07-0809:29:07.612DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'org.springframework.web.context.request.async.WebAsyncManager.WEB_ASYNC_MANAGER'oftype[org.springframework.web.context.request.async.WebAsyncManager]torequestinviewwithname'common/test.html'2015-07-0809:29:07.612DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'org.springframework.web.servlet.DispatcherServlet.CONTEXT'oftype[org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext]torequestinviewwithname'common/test.html'2015-07-0809:29:07.612DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'org.springframework.web.servlet.resource.ResourceUrlProvider'oftype[org.springframework.web.servlet.resource.ResourceUrlProvider]torequestinviewwithname'common/test.html'2015-07-0809:29:07.612DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'characterEncodingFilter.FILTERED'oftype[java.lang.Boolean]torequestinviewwithname'common/test.html'2015-07-0809:29:07.612DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'org.springframework.web.servlet.DispatcherServlet.THEME_SOURCE'oftype[org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext]torequestinviewwithname'common/test.html'2015-07-0809:29:07.612DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'org.springframework.web.servlet.DispatcherServlet.LOCALE_RESOLVER'oftype[org.springframework.web.servlet.i18n.CookieLocaleResolver]torequestinviewwithname'common/test.html'2015-07-0809:29:07.613DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'org.springframework.web.servlet.i18n.CookieLocaleResolver.LOCALE'oftype[java.util.Locale]torequestinviewwithname'common/test.html'2015-07-0809:29:07.613DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'org.springframework.web.servlet.HandlerMapping.bestMatchingPattern'oftype[java.lang.String]torequestinviewwithname'common/test.html'2015-07-0809:29:07.613DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'org.springframework.web.servlet.DispatcherServlet.OUTPUT_FLASH_MAP'oftype[org.springframework.web.servlet.FlashMap]torequestinviewwithname'common/test.html'2015-07-0809:29:07.613DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'org.springframework.web.servlet.HandlerMapping.pathWithinHandlerMapping'oftype[java.lang.String]torequestinviewwithname'common/test.html'2015-07-0809:29:07.613DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'org.springframework.web.servlet.DispatcherServlet.FLASH_MAP_MANAGER'oftype[org.springframework.web.servlet.support.SessionFlashMapManager]torequestinviewwithname'common/test.html'2015-07-0809:29:07.613DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'org.springframework.web.servlet.HandlerMapping.uriTemplateVariables'oftype[java.util.LinkedHashMap]torequestinviewwithname'common/test.html'2015-07-0809:29:07.613DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'org.springframework.web.servlet.DispatcherServlet.THEME_RESOLVER'oftype[org.springframework.web.servlet.theme.CookieThemeResolver]torequestinviewwithname'common/test.html'2015-07-0809:29:07.613DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'org.springframework.core.convert.ConversionService'oftype[org.springframework.format.support.DefaultFormattingConversionService]torequestinviewwithname'common/test.html'2015-07-0809:29:07.613DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'base'oftype[java.lang.String]torequestinviewwithname'common/test.html'2015-07-0809:29:07.613DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'springMacroRequestContext'oftype[org.springframework.web.servlet.support.RequestContext]torequestinviewwithname'common/test.html'2015-07-0809:29:07.615DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :RenderingFreeMarkertemplate[common/test.html]inFreeMarkerView'common/test.html'2015-07-0809:29:07.667 WARN13264---[nio-8080-exec-1]o.s.c.s.ResourceBundleMessageSource   :ResourceBundle[defaultThemeName]notfoundforMessageSource:Can'tfindbundleforbasenamedefaultThemeName,localeen_US 这两行很可疑,为什么主题资源是这个类 org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext 2015-07-0809:29:07.612DEBUG13264---[nio-8080-exec-1]o.s.w.s.view.freemarker.FreeMarkerView :Addedmodelobject'org.springframework.web.servlet.DispatcherServlet.THEME_SOURCE'oftype[org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext]torequestinviewwithname'common/test.html' 配置如下 spring.messages.basename=config/i18nspring.messages.encoding="UTF-8"spring.messages.cacheSeconds=-1spring.theme.basename=config/theme- packagecom.vip.ygd.common;importjavax.servlet.ServletException;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.web.servlet.config.annotation.InterceptorRegistry;importorg.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;importorg.springframework.web.servlet.handler.HandlerInterceptorAdapter;importorg.springframework.web.servlet.i18n.CookieLocaleResolver;importorg.springframework.web.servlet.i18n.LocaleChangeInterceptor;importorg.springframework.web.servlet.theme.CookieThemeResolver;importorg.springframework.web.servlet.theme.ThemeChangeInterceptor;@ConfigurationpublicclassMvcConfigextendsWebMvcConfigurationSupport{@BeanpublicHandlerInterceptorAdapterrequestDefValueInterceptor(){returnnewHandlerInterceptorAdapter(){@OverridepublicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsServletException{request.setAttribute("base",request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath());request.setAttribute("user",request.getSession().getAttribute("user"));returntrue;}@OverridepublicvoidafterCompletion(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,Exceptionex)throwsException{if(ex!=null){//sendmailandlogthis}super.afterCompletion(request,response,handler,ex);}};}@BeanpublicLocaleChangeInterceptorlocaleChangeInterceptor(){returnnewLocaleChangeInterceptor();}@BeanpublicThemeChangeInterceptorthemeChangeInterceptor(){returnnewThemeChangeInterceptor();}@OverrideprotectedvoidaddInterceptors(InterceptorRegistryregistry){registry.addInterceptor(requestDefValueInterceptor());registry.addInterceptor(themeChangeInterceptor());registry.addInterceptor(localeChangeInterceptor());}@Bean(name="themeResolver")publicCookieThemeResolverthemeResolver(){CookieThemeResolverresolver=newCookieThemeResolver();resolver.setCookieMaxAge(31536000);resolver.setCookieName("clienttheme");resolver.setDefaultThemeName("defaultThemeName");returnresolver;}@Bean(name="localeResolver")publicCookieLocaleResolverlocaleResolver(){CookieLocaleResolverresolver=newCookieLocaleResolver();resolver.setCookieName("locale");resolver.setCookieMaxAge(31536000);returnresolver;}//@Bean(name="themeSource")//publicResourceBundleThemeSourcethemeSource(){//ResourceBundleThemeSourcethemeSource=newResourceBundleThemeSource();//themeSource.setBasenamePrefix("classpath:config/theme-");//returnthemeSource;//}//@Bean(name="messageSource")//publicReloadableResourceBundleMessageSourcemessageSource(){//ReloadableResourceBundleMessageSourcebundle=newReloadableResourceBundleMessageSource();//bundle.setBasename("classpath:config/i18n");//bundle.setDefaultEncoding("UTF-8");//bundle.setCacheSeconds(0);//returnbundle;//}} packagecom.vip.ygd.common;importstaticorg.springframework.util.StringUtils.commaDelimitedListToStringArray;importstaticorg.springframework.util.StringUtils.trimAllWhitespace;importjava.io.IOException;importjava.util.Iterator;importjava.util.Set;importorg.springframework.boot.autoconfigure.EnableAutoConfiguration;importorg.springframework.boot.autoconfigure.condition.ConditionOutcome;importorg.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;importorg.springframework.boot.autoconfigure.condition.SpringBootCondition;importorg.springframework.boot.context.properties.ConfigurationProperties;importorg.springframework.boot.context.properties.EnableConfigurationProperties;importorg.springframework.context.MessageSource;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.ConditionContext;importorg.springframework.context.annotation.Conditional;importorg.springframework.context.annotation.Configuration;importorg.springframework.core.Ordered;importorg.springframework.core.annotation.Order;importorg.springframework.core.io.Resource;importorg.springframework.core.io.support.PathMatchingResourcePatternResolver;importorg.springframework.core.type.AnnotatedTypeMetadata;importorg.springframework.ui.context.ThemeSource;importorg.springframework.ui.context.support.ResourceBundleThemeSource;importorg.springframework.util.ConcurrentReferenceHashMap;importorg.springframework.util.StringUtils;importcom.vip.ygd.common.ThemeAutoConfig.ResourceThemeBundleCondition;/***{@linkEnableAutoConfigurationAuto-configuration}for{@linkMessageSource}.**@authorDaveSyer*@authorPhillipWebb*/@Configuration@ConditionalOnMissingBean(ThemeSource.class)@Order(Ordered.HIGHEST_PRECEDENCE)@Conditional(ResourceThemeBundleCondition.class)@EnableConfigurationProperties@ConfigurationProperties(prefix="spring.theme")publicclassThemeAutoConfig{privatestaticfinalResource[]NO_RESOURCES={};/***Comma-separatedlistofbasenames,eachfollowingtheResourceBundleconvention.*Essentiallyafully-qualifiedclasspathlocation.Ifitdoesn'tcontainapackage*qualifier(suchas"org.mypackage"),itwillberesolvedfromtheclasspathroot.*/privateStringbasename="messages";/***Messagebundlesencoding.*/privateStringencoding="utf-8";/***Loadedresourcebundlefilescacheexpiration,inseconds.Whensetto-1,bundles*arecachedforever.*/privateintcacheSeconds=-1;@BeanpublicThemeSourcemessageSource(){ResourceBundleThemeSourcemessageSource=newResourceBundleThemeSource();if(StringUtils.hasText(this.basename)){messageSource.setBasenamePrefix(trimAllWhitespace(this.basename));}returnmessageSource;}publicStringgetBasename(){returnthis.basename;}publicvoidsetBasename(Stringbasename){this.basename=basename;}publicStringgetEncoding(){returnthis.encoding;}publicvoidsetEncoding(Stringencoding){this.encoding=encoding;}publicintgetCacheSeconds(){returnthis.cacheSeconds;}publicvoidsetCacheSeconds(intcacheSeconds){this.cacheSeconds=cacheSeconds;}protectedstaticclassResourceThemeBundleConditionextendsSpringBootCondition{privatestaticConcurrentReferenceHashMap<String,ConditionOutcome>cache=newConcurrentReferenceHashMap<String,ConditionOutcome>();@OverridepublicConditionOutcomegetMatchOutcome(ConditionContextcontext,AnnotatedTypeMetadatametadata){Stringbasename=context.getEnvironment().getProperty("spring.theme.basename","messages");ConditionOutcomeoutcome=cache.get(basename);if(outcome==null){outcome=getMatchOutcomeForBasename(context,basename);cache.put(basename,outcome);}returnoutcome;}privateConditionOutcomegetMatchOutcomeForBasename(ConditionContextcontext,Stringbasename){for(Stringname:commaDelimitedListToStringArray(trimAllWhitespace(basename))){for(Resourceresource:getResources(context.getClassLoader(),name)){if(resource.exists()){returnConditionOutcome.match("Bundlefoundfor"+"spring.theme.basename:"+name);}}}returnConditionOutcome.noMatch("Nobundlefoundfor"+"spring.theme.basename:"+basename);}privateResource[]getResources(ClassLoaderclassLoader,Stringname){try{returnnewSkipPatternPathMatchingResourcePatternResolver(classLoader).getResources("classpath*:"+name+"*.properties");}catch(Exceptionex){returnNO_RESOURCES;}}}/***{@linkPathMatchingResourcePatternResolver}thatskipswellknownJARsthatdon't*containmessages.properties.*/privatestaticclassSkipPatternPathMatchingResourcePatternResolverextendsPathMatchingResourcePatternResolver{privatestaticfinalClassLoaderROOT_CLASSLOADER;static{ClassLoaderclassLoader=null;try{classLoader=ClassLoader.getSystemClassLoader();while(classLoader.getParent()!=null){classLoader=classLoader.getParent();}}catch(Throwableex){}ROOT_CLASSLOADER=classLoader;}privatestaticfinalString[]SKIPPED={"aspectjweaver-","hibernate-core-","hsqldb-","jackson-annotations-","jackson-core-","jackson-databind-","javassist-","snakeyaml-","spring-aop-","spring-beans-","spring-boot-","spring-boot-actuator-","spring-boot-autoconfigure-","spring-core-","spring-context-","spring-data-commons-","spring-expression-","spring-jdbc-","spring-orm-","spring-tx-","spring-web-","spring-webmvc-","tomcat-embed-","joda-time-","hibernate-entitymanager-","hibernate-validator-","logback-classic-","logback-core-","thymeleaf-"};publicSkipPatternPathMatchingResourcePatternResolver(ClassLoaderclassLoader){super(classLoader);}@OverrideprotectedvoidaddAllClassLoaderJarRoots(ClassLoaderclassLoader,Set<Resource>result){if(classLoader!=ROOT_CLASSLOADER){super.addAllClassLoaderJarRoots(classLoader,result);}}@OverrideprotectedSet<Resource>doFindAllClassPathResources(Stringpath)throwsIOException{Set<Resource>resources=super.doFindAllClassPathResources(path);for(Iterator<Resource>iterator=resources.iterator();iterator.hasNext();){Resourceresource=iterator.next();for(Stringskipped:SKIPPED){if(resource.getFilename().startsWith(skipped)){iterator.remove();break;}}}returnresources;}}} 引用来自“逝水fox”的评论得把你配置发出来,看起来像是什么配置有问题这个theme有啥用

爱吃鱼的程序员 2020-06-14 14:49:05 0 浏览量 回答数 0

问题

play 框架中如何在anorm 解析数据库结果时进行datetime格式转换?

蛮大人123 2019-12-01 19:52:09 1609 浏览量 回答数 0

问题

我的比较器方法

montos 2020-03-27 10:11:27 1 浏览量 回答数 1

问题

Android 使用jackson-all-1.7.6.jar混淆出错 can'?报错

优选2 2020-06-09 11:09:36 0 浏览量 回答数 1

问题

Android 使用jackson-all-1.7.6.jar混淆出错 can'?400报错

爱吃鱼的程序员 2020-05-30 17:01:51 0 浏览量 回答数 1

回答

一、Lambda表达式 Lambda表达式可以说是Java 8最大的卖点,她将函数式编程引入了Java。Lambda允许把函数作为一个方法的参数,或者把代码看成数据。 一个Lambda表达式可以由用逗号分隔的参数列表、–>符号与函数体三部分表示。例如: Arrays.asList( "p", "k", "u","f", "o", "r","k").forEach( e -> System.out.println( e ) ); 1 Arrays.asList( "p", "k", "u","f", "o", "r","k").forEach( e -> System.out.println( e ) ); 为了使现有函数更好的支持Lambda表达式,Java 8引入了函数式接口的概念。函数式接口就是只有一个方法的普通接口。java.lang.Runnable与java.util.concurrent.Callable是函数式接口最典型的例子。为此,Java 8增加了一种特殊的注解@FunctionalInterface: 1 @FunctionalInterface2 public interface Functional {3 void method();4 }二、接口的默认方法与静态方法 我们可以在接口中定义默认方法,使用default关键字,并提供默认的实现。所有实现这个接口的类都会接受默认方法的实现,除非子类提供的自己的实现。例如: 1 public interface DefaultFunctionInterface {2 default String defaultFunction() {3 return "default function";4 }5 }我们还可以在接口中定义静态方法,使用static关键字,也可以提供实现。例如: 1 public interface StaticFunctionInterface {2 static String staticFunction() {3 return "static function";4 }5 }接口的默认方法和静态方法的引入,其实可以认为引入了C++中抽象类的理念,以后我们再也不用在每个实现类中都写重复的代码了。 三、方法引用 通常与Lambda表达式联合使用,可以直接引用已有Java类或对象的方法。一般有四种不同的方法引用: 构造器引用。语法是Class::new,或者更一般的Class< T >::new,要求构造器方法是没有参数; 静态方法引用。语法是Class::static_method,要求接受一个Class类型的参数; 特定类的任意对象方法引用。它的语法是Class::method。要求方法是没有参数的; 特定对象的方法引用,它的语法是instance::method。要求方法接受一个参数,与3不同的地方在于,3是在列表元素上分别调用方法,而4是在某个对象上调用方法,将列表元素作为参数传入; 四、重复注解 在Java 5中使用注解有一个限制,即相同的注解在同一位置只能声明一次。Java 8引入重复注解,这样相同的注解在同一地方也可以声明多次。重复注解机制本身需要用@Repeatable注解。Java 8在编译器层做了优化,相同注解会以集合的方式保存,因此底层的原理并没有变化。 五、扩展注解的支持 Java 8扩展了注解的上下文,几乎可以为任何东西添加注解,包括局部变量、泛型类、父类与接口的实现,连方法的异常也能添加注解。 六、Optional Java 8引入Optional类来防止空指针异常,Optional类最先是由Google的Guava项目引入的。Optional类实际上是个容器:它可以保存类型T的值,或者保存null。使用Optional类我们就不用显式进行空指针检查了。 七、Stream Stream API是把真正的函数式编程风格引入到Java中。其实简单来说可以把Stream理解为MapReduce,当然Google的MapReduce的灵感也是来自函数式编程。她其实是一连串支持连续、并行聚集操作的元素。从语法上看,也很像linux的管道、或者链式编程,代码写起来简洁明了,非常酷帅! 八、Date/Time API (JSR 310) Java 8新的Date-Time API (JSR 310)受Joda-Time的影响,提供了新的java.time包,可以用来替代 java.util.Date和java.util.Calendar。一般会用到Clock、LocaleDate、LocalTime、LocaleDateTime、ZonedDateTime、Duration这些类,对于时间日期的改进还是非常不错的。 九、JavaScript引擎Nashorn Nashorn允许在JVM上开发运行JavaScript应用,允许Java与JavaScript相互调用。 十、Base64 在Java 8中,Base64编码成为了Java类库的标准。Base64类同时还提供了对URL、MIME友好的编码器与解码器。 除了这十大新特性之外,还有另外的一些新特性: 更好的类型推测机制:Java 8在类型推测方面有了很大的提高,这就使代码更整洁,不需要太多的强制类型转换了。 编译器优化:Java 8将方法的参数名加入了字节码中,这样在运行时通过反射就能获取到参数名,只需要在编译时使用-parameters参数。 并行(parallel)数组:支持对数组进行并行处理,主要是parallelSort()方法,它可以在多核机器上极大提高数组排序的速度。 并发(Concurrency):在新增Stream机制与Lambda的基础之上,加入了一些新方法来支持聚集操作。 Nashorn引擎jjs:基于Nashorn引擎的命令行工具。它接受一些JavaScript源代码为参数,并且执行这些源代码。 类依赖分析器jdeps:可以显示Java类的包级别或类级别的依赖。 JVM的PermGen空间被移除:取代它的是Metaspace(JEP 122)。

auto_answer 2019-12-02 01:55:13 0 浏览量 回答数 0

回答

一、接口的默认方法 Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用 default关键字即可,这个特征又叫做扩展方法,示例如下: interface Formula { double calculate(int a); default double sqrt(int a) { return Math.sqrt(a); } } Formula接口在拥有calculate方法之外同时还定义了sqrt方法,实现了Formula接口的子类只需要实现一个calculate方法,默认方法sqrt将在子类上可以直接使用。 Formula formula = new Formula() { @Override public double calculate(int a) { return sqrt(a * 100); } }; formula.calculate(100); // 100.0 formula.sqrt(16); // 4.0 文中的formula被实现为一个匿名类的实例,该代码非常容易理解,6行代码实现了计算 sqrt(a * 100)。在下一节中,我们将会看到实现单方法接口的更简单的做法。 译者注: 在Java中只有单继承,如果要让一个类赋予新的特性,通常是使用接口来实现,在C++中支持多继承,允许一个子类同时具有多个父类的接口与功能,在其他语言中,让一个类同时具有其他的可复用代码的方法叫做mixin。新的Java 8 的这个特新在编译器实现的角度上来说更加接近Scala的trait。 在C#中也有名为扩展方法的概念,允许给已存在的类型扩展方法,和Java 8的这个在语义上有差别。 二、Lambda 表达式 首先看看在老版本的Java中是如何排列字符串的: List<String> names = Arrays.asList("peter", "anna", "mike", "xenia"); Collections.sort(names, new Comparator<String>() { @Override public int compare(String a, String b) { return b.compareTo(a); } }); 只需要给静态方法 Collections.sort 传入一个List对象以及一个比较器来按指定顺序排列。通常做法都是创建一个匿名的比较器对象然后将其传递给sort方法。 在Java 8 中你就没必要使用这种传统的匿名对象的方式了,Java 8提供了更简洁的语法,lambda表达式: Collections.sort(names, (String a, String b) -> { return b.compareTo(a); }); 看到了吧,代码变得更段且更具有可读性,但是实际上还可以写得更短: Collections.sort(names, (String a, String b) -> b.compareTo(a)); 对于函数体只有一行代码的,你可以去掉大括号{}以及return关键字,但是你还可以写得更短点: Collections.sort(names, (a, b) -> b.compareTo(a)); Java编译器可以自动推导出参数类型,所以你可以不用再写一次类型。接下来我们看看lambda表达式还能作出什么更方便的东西来 三、函数式接口 Lambda表达式是如何在java的类型系统中表示的呢?每一个lambda表达式都对应一个类型,通常是接口类型。而“函数式接口”是指仅仅只包含一个抽象方法的接口,每一个该类型的lambda表达式都会被匹配到这个抽象方法。因为 默认方法 不算抽象方法,所以你也可以给你的函数式接口添加默认方法。 我们可以将lambda表达式当作任意只包含一个抽象方法的接口类型,确保你的接口一定达到这个要求,你只需要给你的接口添加 @FunctionalInterface 注解,编译器如果发现你标注了这个注解的接口有多于一个抽象方法的时候会报错的。 @FunctionalInterface interface Converter<F, T> { T convert(F from); } Converter<String, Integer> converter = (from) -> Integer.valueOf(from); Integer converted = converter.convert("123"); System.out.println(converted); // 123 需要注意如果@FunctionalInterface如果没有指定,上面的代码也是对的。 译者注 将lambda表达式映射到一个单方法的接口上,这种做法在Java 8之前就有别的语言实现,比如Rhino JavaScript解释器,如果一个函数参数接收一个单方法的接口而你传递的是一个function,Rhino 解释器会自动做一个单接口的实例到function的适配器,典型的应用场景有 org.w3c.dom.events.EventTarget 的addEventListener 第二个参数 EventListener。 四、方法与构造函数引用 前一节中的代码还可以通过静态方法引用来表示: Converter<String, Integer> converter = Integer::valueOf; Integer converted = converter.convert("123"); System.out.println(converted); // 123 Java 8 允许你使用 :: 关键字来传递方法或者构造函数引用,上面的代码展示了如何引用一个静态方法,我们也可以引用一个对象的方法: converter = something::startsWith; String converted = converter.convert("Java"); System.out.println(converted); // "J" 接下来看看构造函数是如何使用::关键字来引用的,首先我们定义一个包含多个构造函数的简单类: class Person { String firstName; String lastName; Person() {} Person(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } } 接下来我们指定一个用来创建Person对象的对象工厂接口: interface PersonFactory<P extends Person> { P create(String firstName, String lastName); } 这里我们使用构造函数引用来将他们关联起来,而不是实现一个完整的工厂: PersonFactory<Person> personFactory = Person::new; Person person = personFactory.create("Peter", "Parker"); 我们只需要使用 Person::new 来获取Person类构造函数的引用,Java编译器会自动根据PersonFactory.create方法的签名来选择合适的构造函数。 五、Lambda 作用域 在lambda表达式中访问外层作用域和老版本的匿名对象中的方式很相似。你可以直接访问标记了final的外层局部变量,或者实例的字段以及静态变量。 六、访问局部变量 我们可以直接在lambda表达式中访问外层的局部变量: final int num = 1; Converter<Integer, String> stringConverter = (from) -> String.valueOf(from + num); stringConverter.convert(2); // 3 但是和匿名对象不同的是,这里的变量num可以不用声明为final,该代码同样正确: int num = 1; Converter<Integer, String> stringConverter = (from) -> String.valueOf(from + num); stringConverter.convert(2); // 3 不过这里的num必须不可被后面的代码修改(即隐性的具有final的语义),例如下面的就无法编译: int num = 1; Converter<Integer, String> stringConverter = (from) -> String.valueOf(from + num); num = 3; 在lambda表达式中试图修改num同样是不允许的。 七、访问对象字段与静态变量 和本地变量不同的是,lambda内部对于实例的字段以及静态变量是即可读又可写。该行为和匿名对象是一致的: class Lambda4 { static int outerStaticNum; int outerNum; void testScopes() { Converter<Integer, String> stringConverter1 = (from) -> { outerNum = 23; return String.valueOf(from); }; Converter<Integer, String> stringConverter2 = (from) -> { outerStaticNum = 72; return String.valueOf(from); }; } } 八、访问接口的默认方法 还记得第一节中的formula例子么,接口Formula定义了一个默认方法sqrt可以直接被formula的实例包括匿名对象访问到,但是在lambda表达式中这个是不行的。 Lambda表达式中是无法访问到默认方法的,以下代码将无法编译: Formula formula = (a) -> sqrt( a * 100); Built-in Functional Interfaces JDK 1.8 API包含了很多内建的函数式接口,在老Java中常用到的比如Comparator或者Runnable接口,这些接口都增加了@FunctionalInterface注解以便能用在lambda上。 Java 8 API同样还提供了很多全新的函数式接口来让工作更加方便,有一些接口是来自Google Guava库里的,即便你对这些很熟悉了,还是有必要看看这些是如何扩展到lambda上使用的。 Predicate接口 Predicate 接口只有一个参数,返回boolean类型。该接口包含多种默认方法来将Predicate组合成其他复杂的逻辑(比如:与,或,非): Predicate<String> predicate = (s) -> s.length() > 0; predicate.test("foo"); // true predicate.negate().test("foo"); // false Predicate<Boolean> nonNull = Objects::nonNull; Predicate<Boolean> isNull = Objects::isNull; Predicate<String> isEmpty = String::isEmpty; Predicate<String> isNotEmpty = isEmpty.negate(); Function 接口 Function 接口有一个参数并且返回一个结果,并附带了一些可以和其他函数组合的默认方法(compose, andThen): Function<String, Integer> toInteger = Integer::valueOf; Function<String, String> backToString = toInteger.andThen(String::valueOf); backToString.apply("123"); // "123" Supplier 接口 Supplier 接口返回一个任意范型的值,和Function接口不同的是该接口没有任何参数 Supplier personSupplier = Person::new; personSupplier.get(); // new Person Consumer 接口 Consumer 接口表示执行在单个参数上的操作。 Consumer greeter = (p) -> System.out.println("Hello, " + p.firstName); greeter.accept(new Person("Luke", "Skywalker")); Comparator 接口 Comparator 是老Java中的经典接口, Java 8在此之上添加了多种默认方法: Comparator comparator = (p1, p2) -> p1.firstName.compareTo(p2.firstName); Person p1 = new Person("John", "Doe"); Person p2 = new Person("Alice", "Wonderland"); comparator.compare(p1, p2); // > 0 comparator.reversed().compare(p1, p2); // < 0 Optional 接口 Optional 不是函数是接口,这是个用来防止NullPointerException异常的辅助类型,这是下一届中将要用到的重要概念,现在先简单的看看这个接口能干什么: Optional 被定义为一个简单的容器,其值可能是null或者不是null。在Java 8之前一般某个函数应该返回非空对象但是偶尔却可能返回了null,而在Java 8中,不推荐你返回null而是返回Optional。 Optional optional = Optional.of("bam"); optional.isPresent(); // true optional.get(); // "bam" optional.orElse("fallback"); // "bam" optional.ifPresent((s) -> System.out.println(s.charAt(0))); // "b" Stream 接口 java.util.Stream 表示能应用在一组元素上一次执行的操作序列。Stream 操作分为中间操作或者最终操作两种,最终操作返回一特定类型的计算结果,而中间操作返回Stream本身,这样你就可以将多个操作依次串起来。Stream 的创建需要指定一个数据源,比如 java.util.Collection的子类,List或者Set, Map不支持。Stream的操作可以串行执行或者并行执行。 首先看看Stream是怎么用,首先创建实例代码的用到的数据List: List stringCollection = new ArrayList<>(); stringCollection.add("ddd2"); stringCollection.add("aaa2"); stringCollection.add("bbb1"); stringCollection.add("aaa1"); stringCollection.add("bbb3"); stringCollection.add("ccc"); stringCollection.add("bbb2"); stringCollection.add("ddd1"); Java 8扩展了集合类,可以通过 Collection.stream() 或者 Collection.parallelStream() 来创建一个Stream。下面几节将详细解释常用的Stream操作: Filter 过滤 过滤通过一个predicate接口来过滤并只保留符合条件的元素,该操作属于中间操作,所以我们可以在过滤后的结果来应用其他Stream操作(比如forEach)。forEach需要一个函数来对过滤后的元素依次执行。forEach是一个最终操作,所以我们不能在forEach之后来执行其他Stream操作。 stringCollection .stream() .filter((s) -> s.startsWith("a")) .forEach(System.out::println); // "aaa2", "aaa1" Sort 排序 排序是一个中间操作,返回的是排序好后的Stream。如果你不指定一个自定义的Comparator则会使用默认排序。 stringCollection .stream() .sorted() .filter((s) -> s.startsWith("a")) .forEach(System.out::println); // "aaa1", "aaa2" 需要注意的是,排序只创建了一个排列好后的Stream,而不会影响原有的数据源,排序之后原数据stringCollection是不会被修改的。 System.out.println(stringCollection); // ddd2, aaa2, bbb1, aaa1, bbb3, ccc, bbb2, ddd1 Map 映射 中间操作map会将元素根据指定的Function接口来依次将元素转成另外的对象,下面的示例展示了将字符串转换为大写字符串。你也可以通过map来讲对象转换成其他类型,map返回的Stream类型是根据你map传递进去的函数的返回值决定的。 stringCollection .stream() .map(String::toUpperCase) .sorted((a, b) -> b.compareTo(a)) .forEach(System.out::println); // "DDD2", "DDD1", "CCC", "BBB3", "BBB2", "AAA2", "AAA1" Match 匹配 Stream提供了多种匹配操作,允许检测指定的Predicate是否匹配整个Stream。所有的匹配操作都是最终操作,并返回一个boolean类型的值。 boolean anyStartsWithA = stringCollection .stream() .anyMatch((s) -> s.startsWith("a")); System.out.println(anyStartsWithA); // true boolean allStartsWithA = stringCollection .stream() .allMatch((s) -> s.startsWith("a")); System.out.println(allStartsWithA); // false boolean noneStartsWithZ = stringCollection .stream() .noneMatch((s) -> s.startsWith("z")); System.out.println(noneStartsWithZ); // true Count 计数 计数是一个最终操作,返回Stream中元素的个数,返回值类型是long。 long startsWithB = stringCollection .stream() .filter((s) -> s.startsWith("b")) .count(); System.out.println(startsWithB); // 3 Reduce 规约 这是一个最终操作,允许通过指定的函数来讲stream中的多个元素规约为一个元素,规越后的结果是通过Optional接口表示的: Optional reduced = stringCollection .stream() .sorted() .reduce((s1, s2) -> s1 + "#" + s2); reduced.ifPresent(System.out::println); // "aaa1#aaa2#bbb1#bbb2#bbb3#ccc#ddd1#ddd2" 并行Streams 前面提到过Stream有串行和并行两种,串行Stream上的操作是在一个线程中依次完成,而并行Stream则是在多个线程上同时执行。 下面的例子展示了是如何通过并行Stream来提升性能: 首先我们创建一个没有重复元素的大表 int max = 1000000; List values = new ArrayList<>(max); for (int i = 0; i < max; i++) { UUID uuid = UUID.randomUUID(); values.add(uuid.toString()); } 然后我们计算一下排序这个Stream要耗时多久, 串行排序: long t0 = System.nanoTime(); long count = values.stream().sorted().count(); System.out.println(count); long t1 = System.nanoTime(); long millis = TimeUnit.NANOSECONDS.toMillis(t1 - t0); System.out.println(String.format("sequential sort took: %d ms", millis)); // 串行耗时: 899 ms 并行排序: long t0 = System.nanoTime(); long count = values.parallelStream().sorted().count(); System.out.println(count); long t1 = System.nanoTime(); long millis = TimeUnit.NANOSECONDS.toMillis(t1 - t0); System.out.println(String.format("parallel sort took: %d ms", millis)); // 并行排序耗时: 472 ms 上面两个代码几乎是一样的,但是并行版的快了50%之多,唯一需要做的改动就是将stream()改为parallelStream()。 Map 前面提到过,Map类型不支持stream,不过Map提供了一些新的有用的方法来处理一些日常任务。 Map<Integer, String> map = new HashMap<>(); for (int i = 0; i < 10; i++) { map.putIfAbsent(i, "val" + i); } map.forEach((id, val) -> System.out.println(val)); 以上代码很容易理解, putIfAbsent 不需要我们做额外的存在性检查,而forEach则接收一个Consumer接口来对map里的每一个键值对进行操作。 下面的例子展示了map上的其他有用的函数: map.computeIfPresent(3, (num, val) -> val + num); map.get(3); // val33 map.computeIfPresent(9, (num, val) -> null); map.containsKey(9); // false map.computeIfAbsent(23, num -> "val" + num); map.containsKey(23); // true map.computeIfAbsent(3, num -> "bam"); map.get(3); // val33 接下来展示如何在Map里删除一个键值全都匹配的项 map.remove(3, "val3"); map.get(3); // val33 map.remove(3, "val33"); map.get(3); // null 另外一个有用的方法 map.getOrDefault(42, "not found"); // not found 对Map的元素做合并也变得很容易了: map.merge(9, "val9", (value, newValue) -> value.concat(newValue)); map.get(9); // val9 map.merge(9, "concat", (value, newValue) -> value.concat(newValue)); map.get(9); // val9concat Merge做的事情是如果键名不存在则插入,否则则对原键对应的值做合并操作并重新插入到map中。 九、Date API Java 8 在包java.time下包含了一组全新的时间日期API。新的日期API和开源的Joda-Time库差不多,但又不完全一样,下面的例子展示了这组新API里最重要的一些部分: Clock 时钟 Clock类提供了访问当前日期和时间的方法,Clock是时区敏感的,可以用来取代 System.currentTimeMillis() 来获取当前的微秒数。某一个特定的时间点也可以使用Instant类来表示,Instant类也可以用来创建老的java.util.Date对象。 Clock clock = Clock.systemDefaultZone(); long millis = clock.millis(); Instant instant = clock.instant(); Date legacyDate = Date.from(instant); // legacy java.util.Date Timezones 时区 在新API中时区使用ZoneId来表示。时区可以很方便的使用静态方法of来获取到。 时区定义了到UTS时间的时间差,在Instant时间点对象到本地日期对象之间转换的时候是极其重要的。 System.out.println(ZoneId.getAvailableZoneIds()); // prints all available timezone ids ZoneId zone1 = ZoneId.of("Europe/Berlin"); ZoneId zone2 = ZoneId.of("Brazil/East"); System.out.println(zone1.getRules()); System.out.println(zone2.getRules()); // ZoneRules[currentStandardOffset=+01:00] // ZoneRules[currentStandardOffset=-03:00] LocalTime 本地时间 LocalTime 定义了一个没有时区信息的时间,例如 晚上10点,或者 17:30:15。下面的例子使用前面代码创建的时区创建了两个本地时间。之后比较时间并以小时和分钟为单位计算两个时间的时间差: LocalTime now1 = LocalTime.now(zone1); LocalTime now2 = LocalTime.now(zone2); System.out.println(now1.isBefore(now2)); // false long hoursBetween = ChronoUnit.HOURS.between(now1, now2); long minutesBetween = ChronoUnit.MINUTES.between(now1, now2); System.out.println(hoursBetween); // -3 System.out.println(minutesBetween); // -239 LocalTime 提供了多种工厂方法来简化对象的创建,包括解析时间字符串。 LocalTime late = LocalTime.of(23, 59, 59); System.out.println(late); // 23:59:59 DateTimeFormatter germanFormatter = DateTimeFormatter .ofLocalizedTime(FormatStyle.SHORT) .withLocale(Locale.GERMAN); LocalTime leetTime = LocalTime.parse("13:37", germanFormatter); System.out.println(leetTime); // 13:37 LocalDate 本地日期 LocalDate 表示了一个确切的日期,比如 2014-03-11。该对象值是不可变的,用起来和LocalTime基本一致。下面的例子展示了如何给Date对象加减天/月/年。另外要注意的是这些对象是不可变的,操作返回的总是一个新实例。 LocalDate today = LocalDate.now(); LocalDate tomorrow = today.plus(1, ChronoUnit.DAYS); LocalDate yesterday = tomorrow.minusDays(2); LocalDate independenceDay = LocalDate.of(2014, Month.JULY, 4); DayOfWeek dayOfWeek = independenceDay.getDayOfWeek(); System.out.println(dayOfWeek); // FRIDAY 从字符串解析一个LocalDate类型和解析LocalTime一样简单: DateTimeFormatter germanFormatter = DateTimeFormatter .ofLocalizedDate(FormatStyle.MEDIUM) .withLocale(Locale.GERMAN); LocalDate xmas = LocalDate.parse("24.12.2014", germanFormatter); System.out.println(xmas); // 2014-12-24 LocalDateTime 本地日期时间 LocalDateTime 同时表示了时间和日期,相当于前两节内容合并到一个对象上了。LocalDateTime和LocalTime还有LocalDate一样,都是不可变的。LocalDateTime提供了一些能访问具体字段的方法。 LocalDateTime sylvester = LocalDateTime.of(2014, Month.DECEMBER, 31, 23, 59, 59); DayOfWeek dayOfWeek = sylvester.getDayOfWeek(); System.out.println(dayOfWeek); // WEDNESDAY Month month = sylvester.getMonth(); System.out.println(month); // DECEMBER long minuteOfDay = sylvester.getLong(ChronoField.MINUTE_OF_DAY); System.out.println(minuteOfDay); // 1439 只要附加上时区信息,就可以将其转换为一个时间点Instant对象,Instant时间点对象可以很容易的转换为老式的java.util.Date。 Instant instant = sylvester .atZone(ZoneId.systemDefault()) .toInstant(); Date legacyDate = Date.from(instant); System.out.println(legacyDate); // Wed Dec 31 23:59:59 CET 2014 格式化LocalDateTime和格式化时间和日期一样的,除了使用预定义好的格式外,我们也可以自己定义格式: DateTimeFormatter formatter = DateTimeFormatter .ofPattern("MMM dd, yyyy - HH:mm"); LocalDateTime parsed = LocalDateTime.parse("Nov 03, 2014 - 07:13", formatter); String string = formatter.format(parsed); System.out.println(string); // Nov 03, 2014 - 07:13 和java.text.NumberFormat不一样的是新版的DateTimeFormatter是不可变的,所以它是线程安全的。 关于时间日期格式的详细信息:http://download.java.net/jdk8/docs/api/java/time/format/DateTimeFormatter.html 十、Annotation 注解 在Java 8中支持多重注解了,先看个例子来理解一下是什么意思。 首先定义一个包装类Hints注解用来放置一组具体的Hint注解: @interface Hints { Hint[] value(); } @Repeatable(Hints.class) @interface Hint { String value(); } Java 8允许我们把同一个类型的注解使用多次,只需要给该注解标注一下@Repeatable即可。 例 1: 使用包装类当容器来存多个注解(老方法) @Hints({@Hint("hint1"), @Hint("hint2")}) class Person {} 例 2:使用多重注解(新方法) @Hint("hint1") @Hint("hint2") class Person {} 第二个例子里java编译器会隐性的帮你定义好@Hints注解,了解这一点有助于你用反射来获取这些信息: Hint hint = Person.class.getAnnotation(Hint.class); System.out.println(hint); // null Hints hints1 = Person.class.getAnnotation(Hints.class); System.out.println(hints1.value().length); // 2 Hint[] hints2 = Person.class.getAnnotationsByType(Hint.class); System.out.println(hints2.length); // 2 即便我们没有在Person类上定义@Hints注解,我们还是可以通过 getAnnotation(Hints.class) 来获取 @Hints注解,更加方便的方法是使用 getAnnotationsByType 可以直接获取到所有的@Hint注解。 另外Java 8的注解还增加到两种新的target上了: @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) @interface MyAnnotation {}

日你dady哟 2019-12-02 03:08:13 0 浏览量 回答数 0
阿里云大学 云服务器ECS com域名 网站域名whois查询 开发者平台 小程序定制 小程序开发 国内短信套餐包 开发者技术与产品 云数据库 图像识别 开发者问答 阿里云建站 阿里云备案 云市场 万网 阿里云帮助文档 免费套餐 开发者工具 企业信息查询 小程序开发制作 视频内容分析 企业网站制作 视频集锦 代理记账服务 2020阿里巴巴研发效能峰会 企业建站模板 云效成长地图 高端建站 阿里云双十一主会场 阿里云双十一新人会场 1024程序员加油包 阿里云双十一拼团会场 场景化解决方案 阿里云双十一直播大厅