Generics Classes with Reflexive Dependency - java

This is something I ran into trying to solve someone else's question here, in a simplified version. Client and Server with reflexive (circular) dependency use generics to try to keep strongly typed references in super class. The wish was for arbitrary sub-type parings such as ClientType1<->ServerType2 , and for strongly typed calls on specialized methods found only in a specific type.
This only works for one level of depth: from server to client, but fails if you then try to continue from that client back to the server:
Is there any syntax which would allow arbitrary levels of strongly typed calls?
abstract class ServerBase<C extends ClientBase<?>>
{
ArrayList<C> clients = new ArrayList<C>();
}
abstract class ClientBase<S extends ServerBase<?>>
{
S server;
}
class ClientType1<S extends ServerBase<?>> extends ClientBase<S>
{
public void clientType1Method() {}
}
class ServerType1<C extends ClientBase<?>> extends ServerBase<C>
{
}
public class Example {
public static void main(String[] args) {
ServerType1<ClientType1<?>> s = new ServerType1<>();
s.clients.get(0).clientType1Method(); // Single depth level - OK
s.clients.get(0).server.clients.get(0).clientType1Method(); // level 2 - compiler error - undefined method
}
}

In my opinion you should not actually need such an intricate reference.
What you really mean is that the client has to hold a reference to a server it can connect, and viceversa.
what should work is:
abstract class ServerBase<C extends ClientBase<? extends ServerBase>>
{
ArrayList<C> clients = new ArrayList<C>();
}
abstract class ClientBase<S extends ServerBase<? extends ClientBase>>
{
S server;
}

If you do a small tweak with this code it will surely work.
abstract class ClientBase<S extends ServerBase<?>> {
S server;
public abstract void clientMethod();
}
.......
public static void main(String[] args) {
ServerType1<ClientBase<?>> s = new ServerType1<>();
s.clients.get(0).clientMethod(); // Single depth level - OK
s.clients.get(0).server.clients.get(0).clientMethod();
// second level - NO compiler error
}

Well, it fails because you have entered yourself a ? instead of an actual type. If you use
ServerType1<ClientType1<ServerType1<ClientType1<?>>>> s = new ServerType1<>();
s.clients.get(0).clientType1Method();
s.clients.get(0).server.clients.get(0).clientType1Method();
instead, it will work. Though it is quite pointless, if we assume that s.clients.get(0).server is the same as s.
Having a circular dependency works only, if you have named types you can refer to, e.g.
public static <S extends ServerType1<ClientType1<S>>> void main(String[] args) {
ServerType1<ClientType1<S>> s = new ServerType1<>();
s.clients.get(0).clientType1Method();
s.clients.get(0).server.clients.get(0).clientType1Method();
s.clients.get(0).server.clients.get(0).server.clients.get(0).clientType1Method();
s.clients.get(0).server.clients.get(0).server.clients.get(0)
.server.clients.get(0).clientType1Method();
s.clients.get(0).server.clients.get(0).server.clients.get(0)
.server.clients.get(0).server.clients.get(0).clientType1Method();
}
Though this is likely to be impractical for most use cases. As soon as you end up having to instantiate S, you would need a real class instead. You should rethink whether you really need such a generic construct. And if you really consider creating such code with helper type variables that are irrelevant to the method’s caller, you should do that with private methods, to avoid them being visible in the public API of your class.

Related

Restrict lambdas on certain interfaces

Assuming I have a couple of interfaces with exactly one abstract method. Having these interfaces, I can declare lambdas with it:
interface A {
int c();
}
interface B {
int c();
}
public class Main {
public static void main(String... args) {
A a = () -> 42;
B b = () -> 42;
}
}
Short question: is there some trick or hack to restrict using interface A for lambdas and fail the build on attempt to do so? Any hint, dirty or not, is welcome (by 'dirty' I mean hacks on compilation/bytecode level - something which won't affect sources and, preferably, public contracts).
Long story: for some interfaces implementors I consider defining equals/hashCode as a part of the contract. Also, I generate equals/hashCode automatically for them at build time.
In this context, lambdas are troublemakers. For ordinary and anonymous implementors of interface A I can find a .class file and instrument its bytecode at build time. For lambdas there is VM-anonymous class, produced at run time. Affecting such class seems impossible at build time, so I need to at least prohibit such occasions for a specific set of interfaces.
Please take a look at my solution on that:
package com.example.demo;
public class LambdaDemo {
public static void main(String[] args) {
//doesn't compile
//LambdaRestrictedInterface x = () -> {};
LambdaRestrictedInterface y = new Test();
y.print();
}
private static class Test implements LambdaRestrictedInterface {
#Override
public void print() {
System.out.println("print");
}
}
public interface MyInterface {
void print();
}
public interface LambdaRestrictedInterface extends MyInterface {
#Override
default void print() {
//hack prevents lambda instantiating
}
}
}
https://dumpz.org/2708733/
Idea is to override parent interface with default impl
Edit from originator: After some consideration, I decided to accept this answer, (since it suited my needs the best and is rather cheap to implement) with some formal additions. In fact, it was realized that the minimal instrumentation which is enough to prevent interface being used as lambda-type is to just add default implementation to its abstract method.
From playing around a bit, it looks like the desc field of the invokedynamic call contains the interface that's being implemented. For instance, when I created a simple () -> {} Runnable and then passed it through ASM's Bytecode Outline plugin, the "ASM-ified" call looked like:
mv.visitInvokeDynamicInsn("run", "()Ljava/lang/Runnable;", new Handle...
So if you're able to do the build-time hack on the call site (as opposed to somehow marking the annotation itself as non-lambda-able, which I don't think you can do) then you should be able to first compile a set of disallowed interfaces, and then check the invokedynamic's desc against that set.

Using Java generics instead of reflection to access common functionality of subclassed objects

I am trying to figure out if generics would be a better way to do what I'm trying to accomplish below (or some other way) instead of using reflection (which I currently have working just fine, but don't like it...).
I have a class library I'm using that is roughly like the following:
abstract class base<T>{
public boolean method1 (String who) {
System.out.println(who+":s");
return true;
}
public T method2 (String who) {
System.out.println(who+":d");
// The following gives me an unchecked cast warning. I can't figure out
// the proper way to fix that either, but it works, so I've moved on...
// In the main program, it's this: obj = (T) in.readObject();
// basically deserializing the object from disk.
return (T) new Object();
}
public abstract void load();
}
class Api1 extends base{
#Override
public void load(){
System.out.println("api1:load()");
}
}
class Api2 extends base{
#Override
public void load(){
System.out.println("api2:load()");
}
}
I am trying to wrap the above class library using the code below... This is what I cannot figure out how to do. The objects that are passed to init() have the same methods (method1(), method2() and load()). I don't want to write init() for each class type, instead, I just want to write it once, then have the compiler handle the details.
UPDATE: There are currently 6 classes that are derived from Base (with a few more likely). In the wrapper, I'm just trying to simplify access to the underlying APIs by handling various housekeeping chores automatically. In the init() method, I need to be able to call the methods of those underlying objects (based on Api1, Api2, ...), without using reflection, or without writing duplicate code for each class, or getting a bunch of unchecked warnings and/or casting...
class ApiWrapper<T>{
// would like to return the type passed in if that's doable
// e.g. public T init(T t)
public void init(T t){
System.out.println("inside init: "+t.getClass().toString());
//t.method1(t.getClass().toString());
//t.method2(t.getClass().toString());
//t.load();
}
}
class api1Wrap extends ApiWrapper {
Api1 api = new Api1();
public api1Wrap(){
init(api);
}
}
class api2Wrap extends ApiWrapper {
Api2 api = new Api2();
public api2Wrap(){
init(api);
}
}
public class GenericApiWrapper {
private final api1Wrap api1;
private final api2Wrap api2;
public GenericApiWrapper() {
this.api1 = new api1Wrap();
this.api2 = new api2Wrap();
}
}
From a main() somewhere ...
GenericApiWrapper gaw = new GenericApiWrapper();
It feels to me like generics are the right approach for this type of thing, but I've been trying all sorts of combinations, and reviewing various articles and examples, but I just can't seem to figure out the proper approach. If this has already been asked and answered, please point me to it. I can't seem to find it, probably because I'm not sure how to describe what I'm trying to do. :) I've been looking at the Java Generics FAQ as well, but I haven't found what I'm looking for... Thanks in advance!
In generics you should specify the type you want to use, in this case you replace the T with for example Api1 otherwise the compiler uses Object:
class api1Wrap extends ApiWrapper<Api1> {
Api1 api = new Api1();
public api1Wrap(){
init(api);
}
}
Also you could improve your code by simple implementing one single class and creating several instances with different types, this is the idea behind generics.
UPDATE:
If you also specify that T extends base, then the compiler is able to find the methods.
Take a look at this:
class ApiWrapper<K, T extends base<K>>{
private T t;
public ApiWrapper(T t){
this.t = t;
}
public void wrap(){
init(t)
}
private void init(T t){
t.method1("hello");
K k = t.method2("world");
}
}
ApiWrapper<Object, Api1> apiWrapper1 = new ApiWrapper<>(new Api1());

Need Clarification in Interface concept in JAVA

I am learning Java Programming and I am a beginner. I am learning Interfaces now. I came across the below two simple examples and I have doubt in those
Program1
public interface Callback {
void callback(int param);
}
class Client implements Callback {
// Implement Callback's interface
public void callback(int p) {
System.out.println("callback called with " + p);
}
void nonIfaceMeth() {
System.out.println("Classes that implement interfaces " +
"may also define other members, too.");
}
}
class TestIface {
public static void main(String args[]) {
Callback c = new Client();
c.callback(42);
// c.nonIfaceMeth();
}
}
Program 2
class Client implements Callback {
// Implement Callback's interface
public void callback(int p) {
System.out.println("callback called with " + p);
}
void nonIfaceMeth() {
System.out.println("Classes that implement interfaces " +
"may also define other members, too.");
}
}
class TestIface {
public static void main(String args[]) {
Client c = new Client();
c.callback(42);
}
}
Both Program1 and Program2 give the same output.
In Program1, variable c is declared to be of the interface type and in Program2, variable c is declared to be of the Class type.
My doubt is what is the difference between these two programs and what are the advantages of creating a Interface type variable ?
Kindly help me t understand the concept. TIA
I will try to keep it short as web is full explainaions on interfaces.
Interface is a contract. Many classes can implement an interface. Using interface is one way to loosly couple your code components.
In Program1, variable c is declared to be of the interface type
This means that any implementation of this interface can be taken to create a concrete object and your code should not break.
and in Program2, variable c is declared to be of the Class type.
This means that you have to change your code to use right class every time you need to use a different implementation. Your code is very cohesive.
It will make more sense when you start studing things like dependency injection or factory pattern etc. Also helpful in unit testing.
UPDATE
Based on your comment
I want the difference between these two statements "Callback c = new
Client();" and "Client c = new Client();"
It is very conceptual at the moment but Callback c = new Client() but allows you to change the type of your varible Cat any time. Lets say there is an other implementation ImportantClient in your code where interface is used to declare the variable you can at any time change it to c = new ImportantClient(). However you can not do that if you are using Client c = new Client();
Both are same in your case when saying
Client c = new Client();
Here actually you are just creating an object of a client. And calling a method of the class Client.
And when you say
Callback c = new Client();
You are just creating a reference of type CallBack but at runtime an Object of Client is being created. So both are same in your case.
In its most common form, an interface is a group of related methods with empty bodies. A bicycle's behavior, if specified as an interface, might appear as follows:
interface Bicycle {
// wheel revolutions per minute
void changeCadence(int newValue);
void changeGear(int newValue);
void speedUp(int increment);
void applyBrakes(int decrement);
}
Reference : Oracle JAVA Documentation
Go through : Using an Interface as a Type
One reason to use an interface is when you want to reduce dependencies between classes or components.
If you have a method that can take an interface as a parameter, for example:
public int countItems(List myList) { ... }
... then you are able to pass in any object whose class implements the List interface, without have that dependency hard coded in the method.
In your case, using the interface Callback enables other classes to be used in the code, if they implement the Callback interface.
Another reason is that it buys you flexibility in choice of concrete class. If you create the object and keep a reference to the interface, it restricts you to only interact with the object through the interface's methods. This means that in future, you could change which concrete class you construct, and as long as it implements the interface, your code will continue to work without requiring modification.

Java instancing an interface results Odd behavior

I am just wandering if following is an odd behaviour.
public interface TestInterfaceTwo {
public void sayBye();
}
public interface TestInterfaceOne {
public void sayHI();
}
public abstract class TestIntefaceClass implements TestInterfaceOne, TestInterfaceTwo {
#Override
public void sayHI() {
System.out.println("HI");
}
#Override
public void sayBye() {
System.out.println("Bye");
}
}
public class InterfaceImplementer extends TestIntefaceClass{
#Override
public void sayHI() {
System.out.println("SAY HI");
}
}
public static void main(String[] args) {
InterfaceImplementer impl = new InterfaceImplementer();
TestInterfaceOne impl1 = new InterfaceImplementer();
TestInterfaceTwo impl2 = new InterfaceImplementer();
TestIntefaceClass impl3 = new InterfaceImplementer();
impl.sayHI();
impl.sayBye();
impl1.sayHI();
impl2.sayBye();
impl.sayBye();
impl3.sayBye();
impl3.sayHI();
}
These calls result the following
SAY HI
Bye
SAY HI
Bye
Bye
Bye
SAY HI
I needed to know if interface instances inherit only the expected behavior from the interface or if it inherits the abstract class. It seems it does the latter and I would like to know an explanation for this and if it is bug Or a feature. :)
This works as expected. I am not entirely sure what is that confuses you.
I needed to know if interface instances inherit only the expected behavior from the interface or if it inherits the abstract class. It seems it does the latter and I would like to know an explanation for this and if it is bug Or a feature. :)
Interfaces don't implement any 'behaviour' (although Java 8 provides default methods) and you can't instantiate one. All those instances you're creating are class instances - in your case, instances of InterfaceImplementer. So let's look at this class and its parent:
TestIntefaceClass implements two interfaces and their methods. Nothing special here.
InterfaceImplementer extends TestIntefaceClass class, it inherits the implementation of sayBye() but it provides its own implementation of sayHi().
Now the following (and the other similar examples from your code)
TestInterfaceOne impl = new InterfaceImplementer();
creates an instance of InterfaceImplementer, as you can see on the right hand side. Thus the implementations that will be used when calling sayHi() and sayBye() will be the ones that Interfaceimplementer overrides / inherits.
LE: This link will probably be useful to you. It discusses using interfaces as types, which is what you're doing.
the "new InterfaceImplementer()" is giving you exactly that ... its just you are decalring them as the various ways .... it's working as expected

Interfaces in Java: cannot make implemented methods protected or private

I know that an interface must be public. However, I don't want that.
I want my implemented methods to only be accessible from their own package, so I want my implemented methods to be protected.
The problem is I can't make the interface or the implemented methods protected.
What is a work around? Is there a design pattern that pertains to this problem?
From the Java guide, an abstract class wouldn't do the job either.
read this.
"The public access specifier indicates that the interface can be used by any class in any package. If you do not specify that the interface is public, your interface will be accessible only to classes defined in the same package as the interface."
Is that what you want?
You class can use package protection and still implement an interface:
class Foo implements Runnable
{
public void run()
{
}
}
If you want some methods to be protected / package and others not, it sounds like your classes have more than one responsibility, and should be split into multiple.
Edit after reading comments to this and other responses:
If your are somehow thinking that the visibility of a method affects the ability to invoke that method, think again. Without going to extremes, you cannot prevent someone from using reflection to identify your class' methods and invoke them. However, this is a non-issue: unless someone is trying to crack your code, they're not going to invoke random methods.
Instead, think of private / protected methods as defining a contract for subclasses, and use interfaces to define the contract with the outside world.
Oh, and to the person who decided my example should use K&R bracing: if it's specified in the Terms of Service, sure. Otherwise, can't you find anything better to do with your time?
When I have butted up against this I use a package accessible inner or nested class to implement the interface, pushing the implemented method out of the public class.
Usually it's because I have a class with a specific public API which must implement something else to get it's job done (quite often because the something else was a callback disguised as an interface <grin>) - this happens a lot with things like Comparable. I don't want the public API polluted with the (forced public) interface implementation.
Hope this helps.
Also, if you truly want the methods accessed only by the package, you don't want the protected scope specifier, you want the default (omitted) scope specifier. Using protected will, of course, allow subclasses to see the methods.
BTW, I think that the reason interface methods are inferred to be public is because it is very much the exception to have an interface which is only implemented by classes in the same package; they are very much most often invoked by something in another package, which means they need to be public.
This question is based on a wrong statement:
I know that an interface must be public
Not really, you can have interfaces with default access modifier.
The problem is I can't make the interface or the implemented methods protected
Here it is:
C:\oreyes\cosas\java\interfaces>type a\*.java
a\Inter.java
package a;
interface Inter {
public void face();
}
a\Face.java
package a;
class Face implements Inter {
public void face() {
System.out.println( "face" );
}
}
C:\oreyes\cosas\java\interfaces>type b\*.java
b\Test.java
package b;
import a.Inter;
import a.Face;
public class Test {
public static void main( String [] args ) {
Inter inter = new Face();
inter.face();
}
}
C:\oreyes\cosas\java\interfaces>javac -d . a\*.java b\Test.java
b\Test.java:2: a.Inter is not public in a; cannot be accessed from outside package
import a.Inter;
^
b\Test.java:3: a.Face is not public in a; cannot be accessed from outside package
import a.Face;
^
b\Test.java:7: cannot find symbol
symbol : class Inter
location: class b.Test
Inter inter = new Face();
^
b\Test.java:7: cannot find symbol
symbol : class Face
location: class b.Test
Inter inter = new Face();
^
4 errors
C:\oreyes\cosas\java\interfaces>
Hence, achieving what you wanted, prevent interface and class usage outside of the package.
Here's how it could be done using abstract classes.
The only inconvenient is that it makes you "subclass".
As per the java guide, you should follow that advice "most" of the times, but I think in this situation it will be ok.
public abstract class Ab {
protected abstract void method();
abstract void otherMethod();
public static void main( String [] args ) {
Ab a = new AbImpl();
a.method();
a.otherMethod();
}
}
class AbImpl extends Ab {
protected void method(){
System.out.println( "method invoked from: " + this.getClass().getName() );
}
void otherMethod(){
System.out.println("This time \"default\" access from: " + this.getClass().getName() );
}
}
Here's another solution, inspired by the C++ Pimpl idiom.
If you want to implement an interface, but don't want that implementation to be public, you can create a composed object of an anonymous inner class that implements the interface.
Here's an example. Let's say you have this interface:
public interface Iface {
public void doSomething();
}
You create an object of the Iface type, and put your implementation in there:
public class IfaceUser {
private int someValue;
// Here's our implementor
private Iface impl = new Iface() {
public void doSomething() {
someValue++;
}
};
}
Whenever you need to invoke doSomething(), you invoke it on your composed impl object.
I just came across this trying to build a protected method with the intention of it only being used in a test case. I wanted to delete test data that I had stuffed into a DB table. In any case I was inspired by #Karl Giesing's post. Unfortunately it did not work. I did figure a way to make it work using a protected inner class.
The interface:
package foo;
interface SomeProtectedFoo {
int doSomeFoo();
}
Then the inner class defined as protected in public class:
package foo;
public class MyFoo implements SomePublicFoo {
// public stuff
protected class ProtectedFoo implements SomeProtectedFoo {
public int doSomeFoo() { ... }
}
protected ProtectedFoo pFoo;
protected ProtectedFoo gimmeFoo() {
return new ProtectedFoo();
}
}
You can then access the protected method only from other classes in the same package, as my test code was as show:
package foo;
public class FooTest {
MyFoo myFoo = new MyFoo();
void doProtectedFoo() {
myFoo.pFoo = myFoo.gimmeFoo();
myFoo.pFoo.doSomeFoo();
}
}
A little late for the original poster, but hey, I just found it. :D
You can go with encapsulation instead of inheritance.
That is, create your class (which won't inherit anything) and in it, have an instance of the object you want to extend.
Then you can expose only what you want.
The obvious disadvantage of this is that you must explicitly pass-through methods for everything you want exposed. And it won't be a subclass...
I would just create an abstract class. There is no harm in it.
With an interface you want to define methods that can be exposed by a variety of implementing classes.
Having an interface with protected methods just wouldn't serve that purpose.
I am guessing your problem can be solved by redesigning your class hierarchy.
One way to get around this is (depending on the situation) to just make an anonymous inner class that implements the interface that has protected or private scope. For example:
public class Foo {
interface Callback {
void hiddenMethod();
}
public Foo(Callback callback) {
}
}
Then in the user of Foo:
public class Bar {
private Foo.Callback callback = new Foo.Callback() {
#Override public void hiddenMethod() { ... }
};
private Foo foo = new Foo(callback);
}
This saves you from having the following:
public class Bar implements Foo.Callback {
private Foo foo = new Foo(this);
// uh-oh! the method is public!
#Override public void hiddenMethod() { ... }
}
I think u can use it now with Java 9 release. From the openJdk notes for Java 9,
Support for private methods in interfaces was briefly in consideration
for inclusion in Java SE 8 as part of the effort to add support for
Lambda Expressions, but was withdrawn to enable better focus on higher
priority tasks for Java SE 8. It is now proposed that support for
private interface methods be undertaken thereby enabling non abstract
methods of an interface to share code between them.
refer https://bugs.openjdk.java.net/browse/JDK-8071453

Categories