Generics and Lambdas cocktail explained - Montreal JUG

Henri Tremblay
Henri TremblayCentral architect
27 au 29 mars 2013
Les lambda sont là!
Mais êtes-vous sûr d'avoir
compris les génériques?
Henri Tremblay
Architecte Senior
Pages Jaunes
@henri_tremblay
Amateur de
Stratégie TI
Performance
Productivité
Bons vins, bières, whiskies…
Fait de l’Open Source
Henri Tremblay
Aime être utile
March 18 2014
Java 7 End of Life
September 2004
Lambda
return Tweet.TWEETS.stream()
.collect(Collectors
.partitioningBy(
t->t.containsHashTag("#lambda")));
Lambda = Fun with generics
Stream<Tweet> stream = Tweet.TWEETS.stream();
Predicate<Tweet> lambda = t -> t.containsHashTag("#lambda");
Collector<Tweet, ?, Map<Boolean, List<Tweet>>> collector =
Collectors.partitioningBy(lambda);
return stream.collect(collector);
Lambda = Fun with generics
Stream<Tweet> stream = Tweet.TWEETS.stream();
Function<Tweet, Boolean> lambda = t -> t.containsHashTag("#lambda");
Collector<Tweet, Map<Boolean, List<Tweet>>> collector =
Collectors.<Tweet, Boolean, List<Tweet>, Map<Boolean, List<Tweet>>>
groupingBy(lambda, HashMap::new, ArrayList::new);
return stream.collect(collector);
What do I need to know?
9© OCTO 2011
Why
What do I need to know?
10© OCTO 2011
Why
Covariance
What do I need to know?
11© OCTO 2011
Why
Covariance
Capture
What do I need to know?
12© OCTO 2011
Why
Covariance
Capture
Inference
What do I need to know?
13© OCTO 2011
Why
Covariance
Capture
Inference
Erasure
What do I need to know?
14© OCTO 2011
Why Covariance
Capture Inference
Erasure Bridge
Faire compiler
15
Dreaded warnings
16
Type safety: The expression of type List needs
unchecked conversion to conform to List<String>
Type safety: Unchecked cast from
List<capture#1-of ?> to List<String>
Ostrich defense
@SuppressWarnings("unchecked")
17
27 au 29 mars 2013
Why
18© OCTO 2011
Rule #1
A code compiling
without warning should
never ever cause a
ClassCastException
19
27 au 29 mars 2013
Covariance
20
Arrays
Arrays are covariant:
Number n = Integer.MAX_VALUE;
Number[] list = new Integer[0];
Generics are not:
List<Number> l =
new ArrayList<Integer>(); // Illegal
21
Why not?
List<Integer> li = new ArrayList<Integer>();
List<Number> ln = li; // illegal
ln.add(new Float(3.1415));
int i = li.get(0); // ClassCastException
22
Would work if covariant And allow to break rule #1
Why for array?
Integer[] list = // ...
foo(list);
public void foo(Object[] o) {
// ...
}
Arrays and generics don’t mix well
Can’t have an array of generics
List<String>[] lsa = new List<String>[10];// illegal
24
Exception
List<?>[] l = new ArrayList<?>[3];
25
Because
If it was allowed
List<String>[] lsa = new List<String>[10]; // illegal
Object[] oa = lsa; // OK (covariant)
oa[0] = new ArrayList<Integer>(); // OK
oa[0].add(42);
String s = lsa[0].get(0); // bad
26
27 au 29 mars 2013
Capture
27
Capture usually is
Type
List<?> bar();
<T> IExpectationSetters<T> expect(T value);
void andReturn(T value); // Method of IExpectationSetters
expect(bar()).andReturn(new ArrayList<String>());
And you get
The method andReturn(List<capture#6-of ?>) in the type
IExpectationSetters<List<capture#6-of ?>> is not applicable for the arguments
(ArrayList<String>)
28
Detail
List<?> bar();
<T> IExpectationSetters<T> expect(T value);
void andReturn(T value);
expect(bar()).andReturn(new ArrayList<String>());
List<Capture#6> bar = bar();
IExpectationSetters<List<Capture#6>> es =
expect(bar());
es.andReturn(List<Capture#6> value);
29
Only solution
We need to cast
expect((List<String>) bar()).andReturn(new
ArrayList<String>());
But still a warning
Type safety: Unchecked cast from List<capture#6-of ?> to
List<String>
Framework coder tip:
Try to never return a wildcard unless necessary
30
Tell to expect we want a
List<String>
Inference
31
Diamonds are a programmer best friend
List<String> l = new ArrayList<>();
How the compiler tells the type
<T> T anyObject(T clazz)
33
The parameterDetermine
the return
value type
How the compiler tells the type
MyType var = <T> T anyObject()
34
Determine the
return type
The assigned
variable
But watch out with overloading
public void foo(String s)
public void foo(Object o)
foo(anyObject());
35
Can’t
guess the
type
Trick #1
<T> T anyObject(Class<T> clazz)
36
Artificially give the type with a
dedicated parameter
Determine the return
value type
But how to pass a generic?
public void foo(String s)
public void foo(Object o)
foo(anyObject(List<String>.class));
37
Illegal
Some solutions
foo((String) anyObject());
foo((List<String>) anyObject()); // Warning
38
This would work
But still doesn’t work for
generics
Trick #2
So the only solution is
foo(EasyMock.<List<String>> anyObject());
… which sadly doesn’t support static imports
foo(.<List<String>> anyObject()); // Illegal
39
Trick #2 applied to Lambda
return Tweet.TWEETS.stream()
.collect( Collectors.<Tweet, Boolean,
List<Tweet>, Map<Boolean, List<Tweet>>>
groupingBy(t->t.containsHashTag("#lambda"),
HashMap::new, ArrayList::new));
Return type: Map<Boolean, List<Tweet>>
Lambda = Inference
return Tweet.TWEETS.stream()
.collect(Collectors
.partitioningBy(
t->t.containsHashTag("#lambda"));
How did it do it?
Tweet.TWEETS.stream()
List<Tweet> list = Tweet.TWEETS;
Stream<Tweet> stream = list.stream();
How did it do it?
Stream<Tweet> stream = list.stream();
R result = stream.collect(Collector<? super T, ?, R> collector);
R result = stream.collect(Collector<? super Tweet, ?, R> collector);
How did it do it?
stream.collect(Collector<? super Tweet, ?, R> collector);
Collector<T, ?, Map<Boolean, List<T>>> collector =
Collectors.partitioningBy(Predicate<? super T> predicate);
Collector<Tweet, ?, Map<Boolean, List<Tweet>>> collector =
Collectors.partitioningBy(Predicate<? super Tweet> predicate);
How did it do it?
Predicate<? super Tweet> lambda = t -> t.containsHashTag("#lambda");
We now know that
So the best t can be is a Tweet
Predicate<? super Tweet> lambda = (Tweet t) -> t.containsHashTag("#lambda");
Trick #3: Lambda inference
Object o = (Runnable) () -> {
System.out.println("hi");
};
Collections.sort(strings,
(String a, String b) -> a.compareTo(b));
Erasure
47
Erasure…
public void foo() {
List<String> l = new ArrayList<String>();
for (String s : l) {
System.out.println(s);
}
}
No type
public void foo() {
List l = new ArrayList();
for (String s : l) {
System.out.println(s);
}
}
Compilation
… or not erasure
public class A extends ArrayList<String> {}
public static void main(final String[] args) {
ParameterizedType type = (ParameterizedType)
A.class.getGenericSuperclass();
System.out.println(
type.getActualTypeArguments()[0]);
}
 prints class java.lang.String
49
Type class
java.lang.reflect.Type
• GenericArrayType
• ParameterizedType
• TypeVariable
• WildcardType
• Implemented by Class
java.lang.reflect.GenericDeclaration
Implemented by Class, Method, Constructor
50
New powers unleashed!
Useful!
class A {}
abstract class BaseDao<T> {
public T load(final long id) {
// …
}
}
class ADao extends BaseDao<A> {}
51© OCTO 2011
Useful!
@SuppressWarnings("unchecked")
public T load(final long id) {
ParameterizedType type =
(ParameterizedType) getClass()
.getGenericSuperclass();
Type actualType = type.getActualTypeArguments()[0];
return em.find((Class<T>) actualType, (Long) id);
}
ADao
A
BaseDao<A>
Unsafe cast
Bridge
53© OCTO 2011
Everything seems normal…
class A<T> {
abstract void set(T value);
}
class B extends A<String> {
String value;
@Override
void set(final String value) {
this.value = value;
}
}
But is not
class B extends A {
void set(String value) {
this.value = value;
}
volatile void set(Object o){
set((String)o);
}
}
Example
A a = new B();
a.set(new Object());
But at runtime:
java.lang.ClassCastException
Raw type warning Perfectly compiling
The actual problem being
B.class.getDeclaredMethods()
volatile void set(java.lang.Object)
void B.set(java.lang.String)
This
Returns that
And gives you no way to find out
which method is bridged
What about lambdas?
public class A {
public static void main(String[] args) {
Method[] methods = A.class.getDeclaredMethods();
Arrays.stream(methods).forEach(m ->
System.out.println(m + " "
+ m.isBridge() + " " + m.isSynthetic()));
}
}
Prints this
public static void A.main(java.lang.String[]) false false
private static void A.lambda$0(java.lang.reflect.Method) false true
Conclusion
Who has learned
something today?
59© OCTO 2011
Useful links
Nice lambda tutorial (in French):
http://lambda.ninjackaton.ninja-squad.com/
Description of inference types on lambda:
http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html
Everything on generics:
http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html
Hopefully everything on lambdas
http://www.lambdafaq.org/
Conclusion
Questions?
61© OCTO 2011
http://perfug.github.io/
http://brownbaglunch.fr
+Henri Tremblay
@henri_tremblay
henri@tremblay.pro
1 sur 61

Recommandé

Java 8, lambdas, generics: How to survive? - NYC Java Meetup Group par
Java 8, lambdas, generics: How to survive? - NYC Java Meetup GroupJava 8, lambdas, generics: How to survive? - NYC Java Meetup Group
Java 8, lambdas, generics: How to survive? - NYC Java Meetup GroupHenri Tremblay
1.4K vues61 diapositives
JavaOne 2016 - Learn Lambda and functional programming par
JavaOne 2016 - Learn Lambda and functional programmingJavaOne 2016 - Learn Lambda and functional programming
JavaOne 2016 - Learn Lambda and functional programmingHenri Tremblay
377 vues54 diapositives
Generics and Lambda survival guide - DevNexus 2017 par
Generics and Lambda survival guide - DevNexus 2017Generics and Lambda survival guide - DevNexus 2017
Generics and Lambda survival guide - DevNexus 2017Henri Tremblay
518 vues71 diapositives
学生向けScalaハンズオンテキスト par
学生向けScalaハンズオンテキスト学生向けScalaハンズオンテキスト
学生向けScalaハンズオンテキストOpt Technologies
2K vues212 diapositives
Java 8 - project lambda par
Java 8 - project lambdaJava 8 - project lambda
Java 8 - project lambdaIvar Østhus
3.7K vues31 diapositives
Lambda выражения и Java 8 par
Lambda выражения и Java 8Lambda выражения и Java 8
Lambda выражения и Java 8Alex Tumanoff
4.3K vues25 diapositives

Contenu connexe

Tendances

Procedural Programming: It’s Back? It Never Went Away par
Procedural Programming: It’s Back? It Never Went AwayProcedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayKevlin Henney
2.6K vues158 diapositives
Lec4 par
Lec4Lec4
Lec4Nikhil Chilwant
852 vues25 diapositives
Core csharp and net quick reference par
Core csharp and net quick referenceCore csharp and net quick reference
Core csharp and net quick referenceilesh raval
3.2K vues2 diapositives
Java Generics for Dummies par
Java Generics for DummiesJava Generics for Dummies
Java Generics for Dummiesknutmork
2.9K vues38 diapositives
Functional Programming In Java par
Functional Programming In JavaFunctional Programming In Java
Functional Programming In JavaAndrei Solntsev
3.5K vues39 diapositives
ALF 5 - Parser Top-Down par
ALF 5 - Parser Top-DownALF 5 - Parser Top-Down
ALF 5 - Parser Top-DownAlexandru Radovici
859 vues55 diapositives

Tendances(20)

Procedural Programming: It’s Back? It Never Went Away par Kevlin Henney
Procedural Programming: It’s Back? It Never Went AwayProcedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Kevlin Henney2.6K vues
Core csharp and net quick reference par ilesh raval
Core csharp and net quick referenceCore csharp and net quick reference
Core csharp and net quick reference
ilesh raval3.2K vues
Java Generics for Dummies par knutmork
Java Generics for DummiesJava Generics for Dummies
Java Generics for Dummies
knutmork2.9K vues
Quicksort - a whistle-stop tour of the algorithm in five languages and four p... par Philip Schwarz
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
Quicksort - a whistle-stop tour of the algorithm in five languages and four p...
Philip Schwarz1.2K vues
Refactoring to Immutability par Kevlin Henney
Refactoring to ImmutabilityRefactoring to Immutability
Refactoring to Immutability
Kevlin Henney4.7K vues
Lambda? You Keep Using that Letter par Kevlin Henney
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
Kevlin Henney777 vues
Programming Paradigms Which One Is The Best? par Netguru
Programming Paradigms Which One Is The Best?Programming Paradigms Which One Is The Best?
Programming Paradigms Which One Is The Best?
Netguru59.4K vues
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics par John De Goes
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsQuark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
John De Goes7.2K vues
Porque aprender haskell me fez um programador python melhor? par UFPA
Porque aprender haskell me fez um programador python melhor?Porque aprender haskell me fez um programador python melhor?
Porque aprender haskell me fez um programador python melhor?
UFPA4.7K vues

En vedette

Aula de yoga preço par
Aula de yoga preçoAula de yoga preço
Aula de yoga preçoAruna Yoga
65 vues1 diapositive
Gds amadeus par
Gds amadeusGds amadeus
Gds amadeusmarinelaom
454 vues28 diapositives
Future on power electronics for wind turbine systems par
Future on power electronics for wind turbine systemsFuture on power electronics for wind turbine systems
Future on power electronics for wind turbine systemsKashish Srivastava
649 vues15 diapositives
How to Build Hardware Lean par
How to Build Hardware LeanHow to Build Hardware Lean
How to Build Hardware LeanDiUS
648 vues23 diapositives
Top Ten Reasons Libraries Are Still Important par
Top Ten Reasons Libraries Are Still ImportantTop Ten Reasons Libraries Are Still Important
Top Ten Reasons Libraries Are Still Importantbradspry
4.4K vues12 diapositives
History of Public Libraries par
History of Public LibrariesHistory of Public Libraries
History of Public Librariesannaha
3.9K vues21 diapositives

En vedette(8)

Future on power electronics for wind turbine systems par Kashish Srivastava
Future on power electronics for wind turbine systemsFuture on power electronics for wind turbine systems
Future on power electronics for wind turbine systems
How to Build Hardware Lean par DiUS
How to Build Hardware LeanHow to Build Hardware Lean
How to Build Hardware Lean
DiUS648 vues
Top Ten Reasons Libraries Are Still Important par bradspry
Top Ten Reasons Libraries Are Still ImportantTop Ten Reasons Libraries Are Still Important
Top Ten Reasons Libraries Are Still Important
bradspry4.4K vues
History of Public Libraries par annaha
History of Public LibrariesHistory of Public Libraries
History of Public Libraries
annaha3.9K vues
Exploring food for babies beyond 6 months old par JessWongHuiJuan1
Exploring food for babies beyond 6 months oldExploring food for babies beyond 6 months old
Exploring food for babies beyond 6 months old
JessWongHuiJuan17.3K vues

Similaire à Generics and Lambdas cocktail explained - Montreal JUG

Lambdas and Generics (long version) - Bordeaux/Toulouse JUG par
Lambdas and Generics (long version) - Bordeaux/Toulouse JUGLambdas and Generics (long version) - Bordeaux/Toulouse JUG
Lambdas and Generics (long version) - Bordeaux/Toulouse JUGHenri Tremblay
1.9K vues61 diapositives
Legacy lambda code par
Legacy lambda codeLegacy lambda code
Legacy lambda codePeter Lawrey
1.5K vues35 diapositives
Java 8 Stream API. A different way to process collections. par
Java 8 Stream API. A different way to process collections.Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.David Gómez García
4.4K vues51 diapositives
Java gets a closure par
Java gets a closureJava gets a closure
Java gets a closureTomasz Kowalczewski
1.6K vues56 diapositives
Library functions in c++ par
Library functions in c++Library functions in c++
Library functions in c++Neeru Mittal
1.6K vues16 diapositives
Applying Generics par
Applying GenericsApplying Generics
Applying GenericsBharat17485
612 vues23 diapositives

Similaire à Generics and Lambdas cocktail explained - Montreal JUG(20)

Lambdas and Generics (long version) - Bordeaux/Toulouse JUG par Henri Tremblay
Lambdas and Generics (long version) - Bordeaux/Toulouse JUGLambdas and Generics (long version) - Bordeaux/Toulouse JUG
Lambdas and Generics (long version) - Bordeaux/Toulouse JUG
Henri Tremblay1.9K vues
Java 8 Stream API. A different way to process collections. par David Gómez García
Java 8 Stream API. A different way to process collections.Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.
Library functions in c++ par Neeru Mittal
Library functions in c++Library functions in c++
Library functions in c++
Neeru Mittal1.6K vues
computer notes - Data Structures - 35 par ecomputernotes
computer notes - Data Structures - 35computer notes - Data Structures - 35
computer notes - Data Structures - 35
ecomputernotes11 vues
Linq - an overview par neontapir
Linq - an overviewLinq - an overview
Linq - an overview
neontapir459 vues
Scala Back to Basics: Type Classes par Tomer Gabel
Scala Back to Basics: Type ClassesScala Back to Basics: Type Classes
Scala Back to Basics: Type Classes
Tomer Gabel3.7K vues
CS253: Priority queues (2019) par Jinho Choi
CS253: Priority queues (2019)CS253: Priority queues (2019)
CS253: Priority queues (2019)
Jinho Choi94 vues
C++11 - A Change in Style - v2.0 par Yaser Zhian
C++11 - A Change in Style - v2.0C++11 - A Change in Style - v2.0
C++11 - A Change in Style - v2.0
Yaser Zhian1K vues
Computer notes - Binary Search par ecomputernotes
Computer notes - Binary SearchComputer notes - Binary Search
Computer notes - Binary Search
ecomputernotes2.2K vues
Chapter 22. Lambda Expressions and LINQ par Intro C# Book
Chapter 22. Lambda Expressions and LINQChapter 22. Lambda Expressions and LINQ
Chapter 22. Lambda Expressions and LINQ
Intro C# Book9.6K vues

Plus de Henri Tremblay

DevNexus 2020: Discover Modern Java par
DevNexus 2020: Discover Modern JavaDevNexus 2020: Discover Modern Java
DevNexus 2020: Discover Modern JavaHenri Tremblay
95 vues83 diapositives
OracleCode One 2018: Java 5, 6, 7, 8, 9, 10, 11: What Did You Miss? par
OracleCode One 2018: Java 5, 6, 7, 8, 9, 10, 11: What Did You Miss?OracleCode One 2018: Java 5, 6, 7, 8, 9, 10, 11: What Did You Miss?
OracleCode One 2018: Java 5, 6, 7, 8, 9, 10, 11: What Did You Miss?Henri Tremblay
315 vues79 diapositives
Confoo 2018: Être pragmatique par
Confoo 2018: Être pragmatiqueConfoo 2018: Être pragmatique
Confoo 2018: Être pragmatiqueHenri Tremblay
206 vues67 diapositives
DevNexus 2018: Learn Java 8, lambdas and functional programming par
DevNexus 2018: Learn Java 8, lambdas and functional programmingDevNexus 2018: Learn Java 8, lambdas and functional programming
DevNexus 2018: Learn Java 8, lambdas and functional programmingHenri Tremblay
331 vues36 diapositives
Do you know your mock? - Madras JUG 20171028 par
Do you know your mock? - Madras JUG 20171028Do you know your mock? - Madras JUG 20171028
Do you know your mock? - Madras JUG 20171028Henri Tremblay
126 vues19 diapositives
Be Pragmatic - JavaOne 2017 par
Be Pragmatic - JavaOne 2017Be Pragmatic - JavaOne 2017
Be Pragmatic - JavaOne 2017Henri Tremblay
599 vues64 diapositives

Plus de Henri Tremblay(13)

OracleCode One 2018: Java 5, 6, 7, 8, 9, 10, 11: What Did You Miss? par Henri Tremblay
OracleCode One 2018: Java 5, 6, 7, 8, 9, 10, 11: What Did You Miss?OracleCode One 2018: Java 5, 6, 7, 8, 9, 10, 11: What Did You Miss?
OracleCode One 2018: Java 5, 6, 7, 8, 9, 10, 11: What Did You Miss?
Henri Tremblay315 vues
DevNexus 2018: Learn Java 8, lambdas and functional programming par Henri Tremblay
DevNexus 2018: Learn Java 8, lambdas and functional programmingDevNexus 2018: Learn Java 8, lambdas and functional programming
DevNexus 2018: Learn Java 8, lambdas and functional programming
Henri Tremblay331 vues
Do you know your mock? - Madras JUG 20171028 par Henri Tremblay
Do you know your mock? - Madras JUG 20171028Do you know your mock? - Madras JUG 20171028
Do you know your mock? - Madras JUG 20171028
Henri Tremblay126 vues
Confoo 2016: Initiation aux tests de charge par Henri Tremblay
Confoo 2016: Initiation aux tests de chargeConfoo 2016: Initiation aux tests de charge
Confoo 2016: Initiation aux tests de charge
Henri Tremblay821 vues
Réactif, parallèle, asynchrone. Pourquoi! par Henri Tremblay
Réactif, parallèle, asynchrone. Pourquoi!Réactif, parallèle, asynchrone. Pourquoi!
Réactif, parallèle, asynchrone. Pourquoi!
Henri Tremblay961 vues
Vivre en parallèle - Softshake 2013 par Henri Tremblay
Vivre en parallèle - Softshake 2013Vivre en parallèle - Softshake 2013
Vivre en parallèle - Softshake 2013
Henri Tremblay1.5K vues
Performance perpétuelle (Devopsdays Paris 2013) par Henri Tremblay
Performance perpétuelle (Devopsdays Paris 2013)Performance perpétuelle (Devopsdays Paris 2013)
Performance perpétuelle (Devopsdays Paris 2013)
Henri Tremblay1.9K vues
DevoxxFR 2013: Lambda are coming. Meanwhile, are you sure we've mastered the ... par Henri Tremblay
DevoxxFR 2013: Lambda are coming. Meanwhile, are you sure we've mastered the ...DevoxxFR 2013: Lambda are coming. Meanwhile, are you sure we've mastered the ...
DevoxxFR 2013: Lambda are coming. Meanwhile, are you sure we've mastered the ...
Henri Tremblay1.2K vues

Dernier

Evolving the Network Automation Journey from Python to Platforms par
Evolving the Network Automation Journey from Python to PlatformsEvolving the Network Automation Journey from Python to Platforms
Evolving the Network Automation Journey from Python to PlatformsNetwork Automation Forum
13 vues21 diapositives
Network Source of Truth and Infrastructure as Code revisited par
Network Source of Truth and Infrastructure as Code revisitedNetwork Source of Truth and Infrastructure as Code revisited
Network Source of Truth and Infrastructure as Code revisitedNetwork Automation Forum
26 vues45 diapositives
Future of Indian ConsumerTech par
Future of Indian ConsumerTechFuture of Indian ConsumerTech
Future of Indian ConsumerTechKapil Khandelwal (KK)
21 vues68 diapositives
SAP Automation Using Bar Code and FIORI.pdf par
SAP Automation Using Bar Code and FIORI.pdfSAP Automation Using Bar Code and FIORI.pdf
SAP Automation Using Bar Code and FIORI.pdfVirendra Rai, PMP
23 vues38 diapositives
TouchLog: Finger Micro Gesture Recognition Using Photo-Reflective Sensors par
TouchLog: Finger Micro Gesture Recognition  Using Photo-Reflective SensorsTouchLog: Finger Micro Gesture Recognition  Using Photo-Reflective Sensors
TouchLog: Finger Micro Gesture Recognition Using Photo-Reflective Sensorssugiuralab
19 vues15 diapositives
Special_edition_innovator_2023.pdf par
Special_edition_innovator_2023.pdfSpecial_edition_innovator_2023.pdf
Special_edition_innovator_2023.pdfWillDavies22
17 vues6 diapositives

Dernier(20)

TouchLog: Finger Micro Gesture Recognition Using Photo-Reflective Sensors par sugiuralab
TouchLog: Finger Micro Gesture Recognition  Using Photo-Reflective SensorsTouchLog: Finger Micro Gesture Recognition  Using Photo-Reflective Sensors
TouchLog: Finger Micro Gesture Recognition Using Photo-Reflective Sensors
sugiuralab19 vues
Special_edition_innovator_2023.pdf par WillDavies22
Special_edition_innovator_2023.pdfSpecial_edition_innovator_2023.pdf
Special_edition_innovator_2023.pdf
WillDavies2217 vues
Piloting & Scaling Successfully With Microsoft Viva par Richard Harbridge
Piloting & Scaling Successfully With Microsoft VivaPiloting & Scaling Successfully With Microsoft Viva
Piloting & Scaling Successfully With Microsoft Viva
Serverless computing with Google Cloud (2023-24) par wesley chun
Serverless computing with Google Cloud (2023-24)Serverless computing with Google Cloud (2023-24)
Serverless computing with Google Cloud (2023-24)
wesley chun11 vues
Igniting Next Level Productivity with AI-Infused Data Integration Workflows par Safe Software
Igniting Next Level Productivity with AI-Infused Data Integration Workflows Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Safe Software263 vues
The details of description: Techniques, tips, and tangents on alternative tex... par BookNet Canada
The details of description: Techniques, tips, and tangents on alternative tex...The details of description: Techniques, tips, and tangents on alternative tex...
The details of description: Techniques, tips, and tangents on alternative tex...
BookNet Canada127 vues
Unit 1_Lecture 2_Physical Design of IoT.pdf par StephenTec
Unit 1_Lecture 2_Physical Design of IoT.pdfUnit 1_Lecture 2_Physical Design of IoT.pdf
Unit 1_Lecture 2_Physical Design of IoT.pdf
StephenTec12 vues
GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N... par James Anderson
GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N...GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N...
GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N...
James Anderson85 vues
Voice Logger - Telephony Integration Solution at Aegis par Nirmal Sharma
Voice Logger - Telephony Integration Solution at AegisVoice Logger - Telephony Integration Solution at Aegis
Voice Logger - Telephony Integration Solution at Aegis
Nirmal Sharma39 vues
PharoJS - Zürich Smalltalk Group Meetup November 2023 par Noury Bouraqadi
PharoJS - Zürich Smalltalk Group Meetup November 2023PharoJS - Zürich Smalltalk Group Meetup November 2023
PharoJS - Zürich Smalltalk Group Meetup November 2023
Noury Bouraqadi127 vues

Generics and Lambdas cocktail explained - Montreal JUG

  • 1. 27 au 29 mars 2013 Les lambda sont là! Mais êtes-vous sûr d'avoir compris les génériques? Henri Tremblay Architecte Senior Pages Jaunes @henri_tremblay
  • 2. Amateur de Stratégie TI Performance Productivité Bons vins, bières, whiskies… Fait de l’Open Source Henri Tremblay Aime être utile
  • 4. Java 7 End of Life
  • 7. Lambda = Fun with generics Stream<Tweet> stream = Tweet.TWEETS.stream(); Predicate<Tweet> lambda = t -> t.containsHashTag("#lambda"); Collector<Tweet, ?, Map<Boolean, List<Tweet>>> collector = Collectors.partitioningBy(lambda); return stream.collect(collector);
  • 8. Lambda = Fun with generics Stream<Tweet> stream = Tweet.TWEETS.stream(); Function<Tweet, Boolean> lambda = t -> t.containsHashTag("#lambda"); Collector<Tweet, Map<Boolean, List<Tweet>>> collector = Collectors.<Tweet, Boolean, List<Tweet>, Map<Boolean, List<Tweet>>> groupingBy(lambda, HashMap::new, ArrayList::new); return stream.collect(collector);
  • 9. What do I need to know? 9© OCTO 2011 Why
  • 10. What do I need to know? 10© OCTO 2011 Why Covariance
  • 11. What do I need to know? 11© OCTO 2011 Why Covariance Capture
  • 12. What do I need to know? 12© OCTO 2011 Why Covariance Capture Inference
  • 13. What do I need to know? 13© OCTO 2011 Why Covariance Capture Inference Erasure
  • 14. What do I need to know? 14© OCTO 2011 Why Covariance Capture Inference Erasure Bridge
  • 16. Dreaded warnings 16 Type safety: The expression of type List needs unchecked conversion to conform to List<String> Type safety: Unchecked cast from List<capture#1-of ?> to List<String>
  • 18. 27 au 29 mars 2013 Why 18© OCTO 2011
  • 19. Rule #1 A code compiling without warning should never ever cause a ClassCastException 19
  • 20. 27 au 29 mars 2013 Covariance 20
  • 21. Arrays Arrays are covariant: Number n = Integer.MAX_VALUE; Number[] list = new Integer[0]; Generics are not: List<Number> l = new ArrayList<Integer>(); // Illegal 21
  • 22. Why not? List<Integer> li = new ArrayList<Integer>(); List<Number> ln = li; // illegal ln.add(new Float(3.1415)); int i = li.get(0); // ClassCastException 22 Would work if covariant And allow to break rule #1
  • 23. Why for array? Integer[] list = // ... foo(list); public void foo(Object[] o) { // ... }
  • 24. Arrays and generics don’t mix well Can’t have an array of generics List<String>[] lsa = new List<String>[10];// illegal 24
  • 25. Exception List<?>[] l = new ArrayList<?>[3]; 25
  • 26. Because If it was allowed List<String>[] lsa = new List<String>[10]; // illegal Object[] oa = lsa; // OK (covariant) oa[0] = new ArrayList<Integer>(); // OK oa[0].add(42); String s = lsa[0].get(0); // bad 26
  • 27. 27 au 29 mars 2013 Capture 27
  • 28. Capture usually is Type List<?> bar(); <T> IExpectationSetters<T> expect(T value); void andReturn(T value); // Method of IExpectationSetters expect(bar()).andReturn(new ArrayList<String>()); And you get The method andReturn(List<capture#6-of ?>) in the type IExpectationSetters<List<capture#6-of ?>> is not applicable for the arguments (ArrayList<String>) 28
  • 29. Detail List<?> bar(); <T> IExpectationSetters<T> expect(T value); void andReturn(T value); expect(bar()).andReturn(new ArrayList<String>()); List<Capture#6> bar = bar(); IExpectationSetters<List<Capture#6>> es = expect(bar()); es.andReturn(List<Capture#6> value); 29
  • 30. Only solution We need to cast expect((List<String>) bar()).andReturn(new ArrayList<String>()); But still a warning Type safety: Unchecked cast from List<capture#6-of ?> to List<String> Framework coder tip: Try to never return a wildcard unless necessary 30 Tell to expect we want a List<String>
  • 32. Diamonds are a programmer best friend List<String> l = new ArrayList<>();
  • 33. How the compiler tells the type <T> T anyObject(T clazz) 33 The parameterDetermine the return value type
  • 34. How the compiler tells the type MyType var = <T> T anyObject() 34 Determine the return type The assigned variable
  • 35. But watch out with overloading public void foo(String s) public void foo(Object o) foo(anyObject()); 35 Can’t guess the type
  • 36. Trick #1 <T> T anyObject(Class<T> clazz) 36 Artificially give the type with a dedicated parameter Determine the return value type
  • 37. But how to pass a generic? public void foo(String s) public void foo(Object o) foo(anyObject(List<String>.class)); 37 Illegal
  • 38. Some solutions foo((String) anyObject()); foo((List<String>) anyObject()); // Warning 38 This would work But still doesn’t work for generics
  • 39. Trick #2 So the only solution is foo(EasyMock.<List<String>> anyObject()); … which sadly doesn’t support static imports foo(.<List<String>> anyObject()); // Illegal 39
  • 40. Trick #2 applied to Lambda return Tweet.TWEETS.stream() .collect( Collectors.<Tweet, Boolean, List<Tweet>, Map<Boolean, List<Tweet>>> groupingBy(t->t.containsHashTag("#lambda"), HashMap::new, ArrayList::new)); Return type: Map<Boolean, List<Tweet>>
  • 41. Lambda = Inference return Tweet.TWEETS.stream() .collect(Collectors .partitioningBy( t->t.containsHashTag("#lambda"));
  • 42. How did it do it? Tweet.TWEETS.stream() List<Tweet> list = Tweet.TWEETS; Stream<Tweet> stream = list.stream();
  • 43. How did it do it? Stream<Tweet> stream = list.stream(); R result = stream.collect(Collector<? super T, ?, R> collector); R result = stream.collect(Collector<? super Tweet, ?, R> collector);
  • 44. How did it do it? stream.collect(Collector<? super Tweet, ?, R> collector); Collector<T, ?, Map<Boolean, List<T>>> collector = Collectors.partitioningBy(Predicate<? super T> predicate); Collector<Tweet, ?, Map<Boolean, List<Tweet>>> collector = Collectors.partitioningBy(Predicate<? super Tweet> predicate);
  • 45. How did it do it? Predicate<? super Tweet> lambda = t -> t.containsHashTag("#lambda"); We now know that So the best t can be is a Tweet Predicate<? super Tweet> lambda = (Tweet t) -> t.containsHashTag("#lambda");
  • 46. Trick #3: Lambda inference Object o = (Runnable) () -> { System.out.println("hi"); }; Collections.sort(strings, (String a, String b) -> a.compareTo(b));
  • 48. Erasure… public void foo() { List<String> l = new ArrayList<String>(); for (String s : l) { System.out.println(s); } } No type public void foo() { List l = new ArrayList(); for (String s : l) { System.out.println(s); } } Compilation
  • 49. … or not erasure public class A extends ArrayList<String> {} public static void main(final String[] args) { ParameterizedType type = (ParameterizedType) A.class.getGenericSuperclass(); System.out.println( type.getActualTypeArguments()[0]); }  prints class java.lang.String 49
  • 50. Type class java.lang.reflect.Type • GenericArrayType • ParameterizedType • TypeVariable • WildcardType • Implemented by Class java.lang.reflect.GenericDeclaration Implemented by Class, Method, Constructor 50 New powers unleashed!
  • 51. Useful! class A {} abstract class BaseDao<T> { public T load(final long id) { // … } } class ADao extends BaseDao<A> {} 51© OCTO 2011
  • 52. Useful! @SuppressWarnings("unchecked") public T load(final long id) { ParameterizedType type = (ParameterizedType) getClass() .getGenericSuperclass(); Type actualType = type.getActualTypeArguments()[0]; return em.find((Class<T>) actualType, (Long) id); } ADao A BaseDao<A> Unsafe cast
  • 54. Everything seems normal… class A<T> { abstract void set(T value); } class B extends A<String> { String value; @Override void set(final String value) { this.value = value; } }
  • 55. But is not class B extends A { void set(String value) { this.value = value; } volatile void set(Object o){ set((String)o); } }
  • 56. Example A a = new B(); a.set(new Object()); But at runtime: java.lang.ClassCastException Raw type warning Perfectly compiling
  • 57. The actual problem being B.class.getDeclaredMethods() volatile void set(java.lang.Object) void B.set(java.lang.String) This Returns that And gives you no way to find out which method is bridged
  • 58. What about lambdas? public class A { public static void main(String[] args) { Method[] methods = A.class.getDeclaredMethods(); Arrays.stream(methods).forEach(m -> System.out.println(m + " " + m.isBridge() + " " + m.isSynthetic())); } } Prints this public static void A.main(java.lang.String[]) false false private static void A.lambda$0(java.lang.reflect.Method) false true
  • 59. Conclusion Who has learned something today? 59© OCTO 2011
  • 60. Useful links Nice lambda tutorial (in French): http://lambda.ninjackaton.ninja-squad.com/ Description of inference types on lambda: http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html Everything on generics: http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html Hopefully everything on lambdas http://www.lambdafaq.org/

Notes de l'éditeur

  1. Hors le fait que ça nous donne des magnifiques oneliners, on y croise une quantité particulièrement épique de génériques
  2. Malheureusement, quand on le sépare en petits morceaux, nous voyons apparaître des tonnes de génériques. La bonne nouvelle, c’est que ça s’est amélioré. La dernière fois que j’ai donné cette conférence, ça ressemblait plutôt à ça
  3. L’API était nettement plus complexe et il restait certains problèmes d’inférence L’inférence, c’est le fait de deviner le type. Comme dans le Collectors ici. On en avait un peu depuis l’arrivé des génériques et il y en a maintenant beaucoup plus avec les lambda
  4. Et vous terminez, pas trop fier de vous et pas trop sûr d’avoir compris le problème avec un aborable SuppressWarning. Cette session a pour but de vous faire comprendre 1- Pourquoi vous avez ces erreurs 2- Pourquoi c’est fait comme ça 3- Comment c’est implémenté
  5. Et vous terminez, pas trop fier de vous et pas trop sûr d’avoir compris le problème avec un aborable SuppressWarning. Cette session a pour but de vous faire comprendre 1- Pourquoi vous avez ces erreurs 2- Pourquoi c’est fait comme ça 3- Comment c’est implémenté
  6. Et vous terminez, pas trop fier de vous et pas trop sûr d’avoir compris le problème avec un aborable SuppressWarning. Cette session a pour but de vous faire comprendre 1- Pourquoi vous avez ces erreurs 2- Pourquoi c’est fait comme ça 3- Comment c’est implémenté
  7. Et vous terminez, pas trop fier de vous et pas trop sûr d’avoir compris le problème avec un aborable SuppressWarning. Cette session a pour but de vous faire comprendre 1- Pourquoi vous avez ces erreurs 2- Pourquoi c’est fait comme ça 3- Comment c’est implémenté
  8. Et vous terminez, pas trop fier de vous et pas trop sûr d’avoir compris le problème avec un aborable SuppressWarning. Cette session a pour but de vous faire comprendre 1- Pourquoi vous avez ces erreurs 2- Pourquoi c’est fait comme ça 3- Comment c’est implémenté
  9. Et vous terminez, pas trop fier de vous et pas trop sûr d’avoir compris le problème avec un aborable SuppressWarning. Cette session a pour but de vous faire comprendre 1- Pourquoi vous avez ces erreurs 2- Pourquoi c’est fait comme ça 3- Comment c’est implémenté
  10. Emplit de désespoir vous ne savez pas trop comment vous en débarasser parce que toutes vos tentatives ne compilent pas.
  11. Emplit de désespoir vous ne savez pas trop comment vous en débarasser parce que toutes vos tentatives ne compilent pas.
  12. Et vous terminez, pas trop fier de vous et pas trop sûr d’avoir compris le problème avec un aborable SuppressWarning. Cette session a pour but de vous faire comprendre 1- Pourquoi vous avez ces erreurs 2- Pourquoi c’est fait comme ça 3- Comment c’est implémenté
  13. Par exemple, les arrays
  14. C’est cette règle qui a forcé plusieurs décisions de design et qui a par conséquent rendu notre ami le @SuppressWarning si fréquent. On en vient à ce demander comment ils auraient fait si les annotations n’étaient pas apparu au même moment.
  15. Par exemple, les arrays
  16. Les arrays sont covariants. Si on peut assigner un object d’un type donné à un autre type, alors on peut assigner un array d’objet à un array de l’autre type Par contre pour les génériques on ne peut pas. Il est illégal de faire la ligne du bas. Car, un code qui compile sans warning ne doit jamais jamais causé un ClassCastException
  17. Un exemple que vous avez sûrement déjà vu pour expliquer pourquoi c’est interdit. Comme vous voyez, si la covariance était permisse nous briserions la règle #1 Et pour un array
  18. Parce que pour un tableau, on a envie que ça ça passe
  19. On ne peut pas faire de tableau de génériques et c’est bien dommage. Une seule exception, un tableau de wildcard. Le wildcard étant un type quelconque, nous n’avons pas de soucis. Dans tous les autres cas c’est interdit pour la raison suivante
  20. On ne peut pas faire de tableau de génériques et c’est bien dommage. Une seule exception, un tableau de wildcard. Le wildcard étant un type quelconque, nous n’avons pas de soucis. Dans tous les autres cas c’est interdit pour la raison suivante
  21. Nous avons le cas suivant. Grâce une asticieuse utilisation de la covariance des arrays, si les arrays génériques étaient permis, nous briserions la règle numéro 1. En résumé, si les designers des génériques avaient laissé tomber la règle pour ce cas et laisser le bénéfice du doute au développeur, nous aurions échappé à plusieurs complexité. Je vous laisse juge de leur décision.
  22. Par exemple, les arrays
  23. Une méthode retourne un type en wildcard Pour garder la cohérence, le compilateur va fixer le type et l’appeler capture#6 pour s’assurer de la cohérence du type donné à T Pour les développeurs de framework, ne jamais retourner de wildcard si possible
  24. Une méthode retourne un type en wildcard Pour garder la cohérence, le compilateur va fixer le type et l’appeler capture#6 pour s’assurer de la cohérence du type donné à T Pour les développeurs de framework, ne jamais retourner de wildcard si possible
  25. Warning mandatory pour ne pas enfreindre la règle #1
  26. Par exemple, les arrays
  27. Lorsqu’il y a un paramètre, le compilateur prend le type du paramètre pour déterminer le type de retour. Cette pour cette raison que le syntaxe que vous voyez est apparu en Java 5. Le paramètre ne sert à rien sauf à fixer le type. Mais ça vous les savez sûrement déjà.
  28. Ensuite s’il n’y a pas de paramètre, le compilateur déduit le type à partir de la variable à laquelle elle est assignée. Mais ça ne marche pas à tous les coups.
  29. Dans les cas d’overloading par exemple. Impossible de deviner quelle méthode doit être appelé
  30. Un truc classique est d’ajouter un paramètre juste pour la bonne cause. C’est un contournement classique.
  31. Dans les cas d’overloading par exemple. Impossible de deviner quelle méthode doit être appelé
  32. Pour les lambda, il est très fort probable d’en avoir besoin. Vous avez ici l’exemple du début où je l’utilisais. Fort heureusement, ce n’est pas nécessaire dans la nouvelle API. Par contre, j’ai un peu de difficulté à vous promettre que ce sera toujours le cas. On touche du bois
  33. Par exemple, les arrays
  34. Everybody knows what is erasure? List<String> and ArrayList<String> got erasure The variable in the loop kept is type Boring, nous on va parler des cas où il n’y a pas d’erasure.
  35. Oh dear, no erasure On récupère la classe parent qui s’avère être générique et implémente donc l’interface ParameterizedType.
  36. Il y a eu un ajout de plusieurs interfaces. Elles sont passées presque complètement inaperçu mais peuvent être utile. Par exemple, l’exemple précédent peut servir à faire ça
  37. Par polymorphisme, le getClass() retourne ADao. Donc la superclass est BaseDao, et le type du paramètre générique est A. And yes, the dumb part if the SuppressWarnings. It comes come the (Class<T>) cast. Since the compiler can’t be sure that actualType is a Class, we get the warning. On ne peut pas s’en débarasser.
  38. Par exemple, les arrays
  39. Vous avez une classe générique étendue par un autre qui fixe le type à String. Rien de plus classique.
  40. Magie, à la décompilation, une nouvelle méthode est apparue. C’est le bridge. Elle ne sert à rien sauf à l’assurer c’est bien une String qui est passé en paramètre. Le volatile c’est parce que la modificateur de champs et de méthodes ont des codes communs. Donc en fait, le décompilateur (jad) a un petit bogue. Attention, Java Decompiler ne vous montrera pas le bridge, il le fait disparaitre. On ne le voit qu’avec Jad qui est moins futé.
  41. La règle #1 n’est pas enfreinte car nous avons un warning. Par contre, Java ajoute dans ce cas particulier une sur-protection. Impossible de s’en prémunir à la compilation. Tout est valide. Il fallait donc combler la faille pour empêcher un Object d’être assigné à une String et amener le chaos et l’anarchie dans la JVM. D’où, le bridge.
  42. Vous avez deux méthodes. L’une déléguant directement à l’autre. Si vous avez un framework faisant des proxies dynamiques ou de l’AOP, vous vous retrouvez avec deux méthodes instrumentées. Et c’est assez rare que c’est ce que vous aviez prévus. Résultat, plus rien ne marche. Par exemple, Spring qui utilise beaucoup de proxies, a dû implémenter une class nommée BridgeMethodResolver qui permet de trouver la méthode concrête appelée par le bridge. Et malheureusement, le JDK n’a pas prévu le coup donc il faut la déduire. C’est ce que j’avais de plus compliqué à vous montrer aujourd’hui. Passons donc à la conclusion.
  43. J’ai pas mal pataugé sur ces sujets car ils sont assez peu documentés. C’est pas simple mais on finit par s’y retrouver. La question qui me taraude maintenant c’est “Est-ce que vous connaissiez tout ça?” Pour m’assurez que je ne raconte pas que des banalités. Est-ce que chaque personne pourrait lever la main et me dire si vous avez appris au moins une chose aujourd’hui?
  44. Maurice Naftalin
  45. Oh dear, no erasure