Is possible to create Java generics class depending on int value? - java

We can create a generic class in Java like this
public class MyClass<T> {
...
but, now that i'm translating a (very large) C++ code to Java, i need a class to be different from other depending on its size, like in this c++ code:
template<size_t size> class MyClass {
...
so every class is a different type, there static members are different, and members like "compare" can only be used with objects with the same size.
Is possible to do this in Java? if not, how would you handle this?

Sure, but it sucks.
You can model "counting' with a chain of recursive types. Inc<Inc<Inc<Integer>> could represent 3.
It is exceedingly awkward.
Java generics are not C++ templates. Java generics have a common base implementation and auto write some wrapping code to cast parameterized arguments to/from a common base in a thin wrapper.
C++ templates generate distinct types.
The design of C++ templates was to replace code generation and/or hand-rolled C code low level data structures. The goal was a template class could match or even exceed hand-written C versions (exceed because you can invest more engineering effort into the single template, and reuse it in 100s of spots).
Templates like std::function more closely approach Java generics. While the implementation is dissimilar, here it converts a myriad of types to one interface, hiding the casting from the end user. In C++ this technique is called type erasure, where std function "erases" all information about the stored callable except what it exposes. C++ type erasure does not require a common base class; Java does.
But because Java generics only supports one kind of type erssure, and C++ templates support not only more kinds of type erasure but also entitely different metaprogramming techniques that are alien to Java, replacing templates with Java generics is going to consistently run into problems. Only when the C++ use case happens to perfectly line up with the weaker Java generics does it work right.
(Note that, while weaker, Java generics make type erasure far easier, because they write a bunch of the casting code for you, and type check it. Weaker doesn't mean worse; it often means safer. But mechanically replacing a system with a weaker one often is doomed to failure.)

No, you can't use values as parameters instead of a generic type in Java. You should probably just take the size as a parameter in the constructor and implement safety checks taking the size into account.

Related

Most performant way to achieve type safety on primitive types in Java?

Let's say I'd like to ensure type safety in Java on primitive types. For the sake of an example, let us want to distinguish a Ratio from an AbsoluteValue, both are represented by a double.
Java to my best knowledge does not support type synonyms.
So I'm quite confident some overhead will be involved.
From the top of my head I could think of either defining new calsses which wrap double (a lot of boilerplate), or subclassing Double... or maybe there are even other options?
Which approach gives me the least performance overhead?
EDIT: I'm confined to Java 8, so that's the implicit basis of the question; however, if there are alternative solutions in newer versions of the language I'd still be keen to hear about them.
The most performant way I can think of would be to write your own wrapper classes which have some marker annotation:
#PrimitiveTypeAlias(double.class)
public class Milliseconds
{
double value() { ... }
}
Then hook into the annotation processor at compile-time and physically replace the wrapper classes with their primitive counterparts (using something like Lombok).
... But I suspect you may have been implying "most performant and also low-effort" :)
Take a look a Manifold framework (like Lombok but more concerned with Types than boilerplate reduction). #Extension methods or #Structural interfaces provide various ways of implementing "duck typing" which covers some of the requirement. It won't work directly with primitive fields though. A very basic wrapper class may be optimised by the JIT in various cases (and will be able to use Project Valhalla's inline modifier when that lands).
(I suspect it is a reasonable feature-request to implement first-class aliases to complement Manifold's existing feature set.)

Why does erasure complicate implementing function types?

I read from an interview with Neal Gafter:
"For example, adding function types to the programming language is much more difficult with Erasure as part of Generics."
EDIT:
Another place where I've met similar statement was in Brian Goetz's message in Lambda Dev mailing list, where he says that lambdas are easier to handle when they are just anonymous classes with syntactic sugar:
But my objection to function types was not that I don't like function types -- I love function types -- but that function types fought badly with an existing aspect of the Java type system, erasure. Erased function types are the worst of both worlds. So we removed this from the design.
Can anyone explain these statements? Why would I need runtime type information with lambdas?
The way I understand it, is that they decided that thanks to erasure it would be messy to go the way of 'function types', e.g. delegates in C# and they only could use lambda expressions, which is just a simplification of single abstract method class syntax.
Delegates in C#:
public delegate void DoSomethingDelegate(Object param1, Object param2);
...
//now assign some method to the function type variable (delegate)
DoSomethingDelegate f = DoSomething;
f(new Object(), new Object());
(another sample here
http://geekswithblogs.net/joycsharp/archive/2008/02/15/simple-c-delegate-sample.aspx)
One argument they put forward in Project Lambda docs:
Generic types are erased, which would expose additional places where
developers are exposed to erasure. For example, it would not be
possible to overload methods m(T->U) and m(X->Y), which would be
confusing.
section 2 in:
http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-3.html
(The final lambda expressions syntax will be a bit different from the above document:
http://mail.openjdk.java.net/pipermail/lambda-dev/2011-September/003936.html)
(x, y) => { System.out.printf("%d + %d = %d%n", x, y, x+y); }
All in all, my best understanding is that only a part of syntax stuff that could, actually will be used.
What Neal Gafter most likely meant was that not being able to use delegates will make standard APIs more difficult to adjust to functional style, rather than that javac/JVM update would be more difficult to be done.
If someone understands this better than me, I will be happy to read his account.
Goetz expands on the reasoning in State of the Lambda 4th ed.:
An alternative (or complementary) approach to function types,
suggested by some early proposals, would have been to introduce a new,
structural function type. A type like "function from a String and an
Object to an int" might be expressed as (String,Object)->int. This
idea was considered and rejected, at least for now, due to several
disadvantages:
It would add complexity to the type system and further mix structural and nominal types.
It would lead to a divergence of library styles—some libraries would continue to use callback interfaces, while others would use structural
function types.
The syntax could be unweildy, especially when checked exceptions were included.
It is unlikely that there would be a runtime representation for each distinct function type, meaning developers would be further exposed to
and limited by erasure. For example, it would not be possible (perhaps
surprisingly) to overload methods m(T->U) and m(X->Y).
So, we have instead chosen to take the path of "use what you
know"—since existing libraries use functional interfaces extensively,
we codify and leverage this pattern.
To illustrate, here are some of the functional interfaces in Java SE 7
that are well-suited for being used with the new language features;
the examples that follow illustrate the use of a few of them.
java.lang.Runnable
java.util.concurrent.Callable
java.util.Comparator
java.beans.PropertyChangeListener
java.awt.event.ActionListener
javax.swing.event.ChangeListener
...
Note that erasure is just one of the considerations. In general, the Java lambda approach goes in a different direction from Scala, not just on the typed question. It's very Java-centric.
Maybe because what you'd really want would be a type Function<R, P...>, which is parameterised with a return type and some sequence of parameter types. But because of erasure, you can't have a construct like P..., because it could only turn into Object[], which is too loose to be much use at runtime.
This is pure speculation. I am not a type theorist; i haven't even played one on TV.
I think what he means in that statement is that at runtime Java cannot tell the difference between these two function definitions:
void doIt(List<String> strings) {...}
void doIt(List<Integer> ints) {...}
Because at compile time, the information about what type of data the List contains is erased, so the runtime environment wouldn't be able to determine which function you wanted to call.
Trying to compile both of these methods in the same class will throw the following exception:
doIt(List<String>) clashes with doIt(List<Integer); both methods have the same erasure

What features of Scala cannot be translated to Java?

The Scala compiler compiles direct to Java byte code (or .NET CIL). Some of the features of Scala could be re-done in Java straightforwardly (e.g. simple for comprehensions, classes, translating anonymous/inner functionc etc). What are the features that cannot be translated that way?
That is presumably mostly of academic interest. More usefully, perhaps, what are the key features or idioms of Scala that YOU use that cannot be easily represented in Java?
Are there any the other way about? Things that can be done straightforwardly in Java that have no straightforward equivalent in Scala? Idioms in Java that don't translate?
This question, in my opinion, misses the point about by asking us to compare JVM languages by looking at their generated bytecode.
Scala compiles to Java-equivalent bytecode. That is, the bytecode could have been generated by code written in Java. Indeed you can even get scalac to output an intermediate form which looks a lot like Java.
All features like traits (via static forwarders), non-local returns (via exceptions), lazy values (via references) etc are all expressible by a Java program, although possibly in a most-ugly manner!
But what makes scala scala and not Java is what scalac can do for you, before the bytecode is generated. What scalac has going for it, as a statically typed language, is the ability to check a program for correctness, including type correctness (according to its type system) at compile time.
The major difference then between Java and scala (as of course Java is also statically typed), therefore, is scala's type system, which is capable of expressing programmatic relations which java-the-language's type system cannot.For example:
class Foo[M[_], A](m : M[A])
trait Bar[+A]
These concept, that M is a type parameter which itself has type parameters or that Bar is covariant, just do not exist in Java-land.
Traits are one thing that does not have an equivalent. Traits are Interfaces with code in them. You can copy the code to all classes that have a trait mixed in, but that is not the same thing.
Also I believe scala type system is more complete. While it will eventually map to the JVM types (actually suffer erasure). You can express some things in the Scala type system that may not be possible in Java (like variances).
I think, there is no equivalent for dynamically mix in some Traits. In Scala you can add at the time you're creating new objects some Traits, which are mixed in.
For example, we create one dog which is hungry and thirsty and one dog which is just hungry.
val hungryThirstyDog = new Dog with Hungry with Thirsty
val onlyHungryDog = new Dog with Hungry
I don't know an equivalent way to do this in Java. In Java, the inheritance is statically defined.
Implicit conversions don't have a straightforward equivalent in Java.
One feature of scala that I have found a good use for is type reification through Manifests. Since the JVM strips out all type information from generics, scala allows you to conserve this information in variables. This is something that Java reflection AFAIK can't handle, since there are no arguments to types in the bytecode.
The case I needed them was to pattern match on a type of List. This is, I had a VertexBuffer object which stored data on the GPU, that could be constructed from a List of floats or integers. The Manifest code looked approximately like this:
class VertexBuffer[T](data:List[T])(implicit m:Manifest[T]) {
m.toString.match {
case "float" => ...
case "int" => ...
}
}
This link links to a blog post with more information.
There are plenty of SO pages with more information too, like this one.
Three words: higher kinded types.
Your topic is not clear wehther you mean Java the JVM or Java the language. Given that Scala runs on the JVM, the q makes no sense, as we all know Scala runs on the JVM.
Scala has a "native" support for XML. You can build the XML, find elements, match directly in the Scala code.
Examples: http://programming-scala.labs.oreilly.com/ch10.html

What's the conception behind: Type - Element - Mirror

I'm working with Java 6's annotation processing, i.e. what can be found within javax.annotation.processing (not Java 5's APT).
I wonder what the conceptional difference between the various Element, Type, and Mirror classes is. As I don't really understand this, it's hard to efficiently program an annotation processor. There are various methods that 'convert' between these notions but I'm not really sure what I'm doing when using them.
So, for example, let me have an instance of AnnotationMirror.
When I call getAnnotationType() I get an instance of DeclaredType (which implements TypeMirror for whatever reason).
Then I can call asElement() on this one and obtain an instance of Element.
What has happened?
There is indeed on overlap between these concepts.
Element models the static structure of the program, ie packages, classes, methods and variables. Just think of all you see in the package explorer of Eclipse.
Type models the statically defined type constraints of the program, ie types, generic type parameters, generic type wildcards. Just think of everything that is part of Java's type declarations.
Mirror is an alternative concept to reflection by Gilad Bracha and Dave Ungar initially developed for Self, a prototype-based Smalltalk dialect. The basic idea is to separate queries about the structure of code (and also runtime manipulation of the structure, alas not available in Java) from the domain objects. So to query an object about its methods, instead of calling #getClass you would ask the system for a mirror through which you can see the reflection of the object. Thanks to that separation you can also mirror on classes that are not loaded (as is the case during annotation processing) or even classes in a remote image. For example V8 (Google's Javascript engine) uses mirrors for debugging Javascript code that runs in another object space.
This paper may help understanding the design of Java 6 annotation processing:
Gilad Bracha and David Ungar. Mirrors:
Design Principles for Meta-level
Facilities of Object-Oriented
Programming Languages. In Proc. of
the ACM Conf. on Object-Oriented
Programming, Systems, Languages and
Applications, October 2004.
The object of type javax.lang.model.element.AnnotationMirror represents an annotation in your code.
The declared type represents the annotation class.
Its element is the generic class (see http://java.sun.com/javase/6/docs/api/javax/lang/model/element/TypeElement.html for more information on that matter). The element might be the generic version of a class, like List, where as the declared type is the parametrized version, for instance List<String>. However I'm not sure it is possible to have annotations classes use generics and thus the distinction might be irrelevant in that context.
For instance lets say you have the following JUnit4 method:
#Test(expected = MyException.class)
public void myTest() {
// do some tests on some class...
}
The AnnotationMirror represents #Test(expected = NullPointerException.class). The declared type is the org.junit.Test class. The element is more or less the same as there are no generics involved.

Can we take advantage of the type system to make programs more secure?

This question is inspired from Joel's "Making Wrong Code Look Wrong"
http://www.joelonsoftware.com/articles/Wrong.html
Sometimes you can use types to enforce semantics on objects beyond their interfaces. For example, the Java interface Serializable does not actually define methods, but the fact that an object implements Serializable says something about how it should be used.
Can we have UnsafeString and SafeString interfaces/subclasses in, say Java, that are used in much of the same way as Joel's Hungarian notation and Java's Serializable so that it doesn't just look bad--it doesn't compile?
Is this feasible in Java/C/C++ or are the type systems too weak or too dynamic?
Also, beyond input sanitization, what other security functions can be implemented in this manner?
The type system already enforces a huge number of such safety features. That is essentially what it's for.
For a very simple example, it prevents you from treating a float as an int. That's one aspect of safety -- it guarantees that the type you're working on are going to behave as expected. It guarantees that only string methods are called on a string. Assembly doesn't have that safeguard, for example.
It's also the job of the type system to ensure that you don't call private functions on a class. That's another safety feature.
Java's type system is too anemic to enforce a lot of interesting constraints effectively, but in many other languages (including C++), the type system can be used to enforce far more wide-ranging rules.
In C++, template metaprogramming gives you a lot of tools for prohibiting "bad" code. For example:
class myclass : boost::noncopyable {
...
};
enforces at compile-time that the class can not be copied. The following will produce compile errors:
myclass m;
myclass m2(m); // copy construction isn't allowed
myclass m3;
m3 = m; // assignment also not allowed
Likewise, we can ensure at compile-time that a template function only gets called on types which fulfill certain criteria (say, they must be random-access iterators, while bilinear ones aren't allowed, or they must be POD types, or they must not be any kind of integer type (char, short, int, long), but all other types should be legal.
A textbook example of template metaprogramming in C++ implements a library for computing physical units. It allows you to multiply a value of type "meter" with another value of the same type, and automatically determines that the result must be of type "square meter". Or divide a value of type "mile" with a value of type "hour" and get a unit of type "miles per hour".
Again, a safety feature that prevents you from getting your types mixed up and accidentally getting your units mixed up. You'll get a compile error if you compute a value and try to assign it to the wrong type. trying to divide, say, liters by meters^2 and assigning the result to a value of, say, kilograms, will result in a compile error.
Most of this requires some manual work to set up, certainly, but the language gives you the tools you need to basically build the type-checks you want. Some of this could be better supported directly in the language, but the more creative checks would have to be implemented manually in any case.
Yes you can do such thing. I don't know about Java, but in C++ it isn't customary and there is no support for this, so you have to do some manual work. It is customary in some other languages, Ada for example, which have the equivalent of a typedef which introduces a new type which can't be converted implicitly into the orignal one (this new type "inherits" some basic operations from the one it is created, so it stays usefull).
BTW, in general inheritance isn't a good way to introduce the new types, as even if there is no implicit conversion in one way, there is one in the other one.
You can do a certian amount of this out of the box in Ada. For example, you can make integer types that cannot implcitily interoperate with each other, and Ada enumerations are not compatible with any integer type. You can still convert between them, but you have to explicitly do it, which calls attention to what you are doing.
You could do the same with present-day C++, but you'd have to wrap all your integers and enums in classes, which is just way too much work for something that should be simple (or better yet, the default way of doing things).
I understand the next version of C++ is going to fix at least the enumeration issue.
In C++, I suppose you could use typedef to create a synonym for a primitive type. Your synonym could imply something about the content of that variable, replacing the function of the apps hungarian notation.
Intellisense will report the synonym you used during declaration, so if you don't like using actual hungarian, it does save you from scrolling about (or using Go To Definition).
I guess you are thinking of something along the lines of Perl's "tainting" analysis.
In Java, it should be possible to use custom annotations and an annotation processor to implement this. Not necessarily easy though.
You can't have a UnsafeString subclass of String in Java, since java.lang.String is final.
In general, you cannot provide any kind of security on the source level - if you want to protect against evil code, you must do that on the binary level (e.g. Java bytecode). That's why private/protected can't be used as a security mechanism in C++: it is possible to bypass that with pointer manipulations.

Categories

Resources